@elizaos/plugin-inbox 2.0.3-beta.6 → 2.0.3-beta.7
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/dist/actions/inbox.d.ts +69 -0
- package/dist/actions/inbox.d.ts.map +1 -0
- package/dist/actions/inbox.js +345 -0
- package/dist/actions/inbox.js.map +1 -0
- package/dist/components/inbox/InboxSpatialView.d.ts +54 -0
- package/dist/components/inbox/InboxSpatialView.d.ts.map +1 -0
- package/dist/components/inbox/InboxSpatialView.js +171 -0
- package/dist/components/inbox/InboxSpatialView.js.map +1 -0
- package/dist/components/inbox/InboxView.d.ts +64 -0
- package/dist/components/inbox/InboxView.d.ts.map +1 -0
- package/dist/components/inbox/InboxView.js +169 -0
- package/dist/components/inbox/InboxView.js.map +1 -0
- package/dist/components/inbox/inbox-view-bundle.d.ts +2 -0
- package/dist/components/inbox/inbox-view-bundle.d.ts.map +1 -0
- package/dist/components/inbox/inbox-view-bundle.js +5 -0
- package/dist/components/inbox/inbox-view-bundle.js.map +1 -0
- package/dist/db/index.d.ts +3 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +3 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.d.ts +1729 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +79 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/sql.d.ts +32 -0
- package/dist/db/sql.d.ts.map +1 -0
- package/dist/db/sql.js +130 -0
- package/dist/db/sql.js.map +1 -0
- package/dist/inbox/channel-deep-links.d.ts +7 -0
- package/dist/inbox/channel-deep-links.d.ts.map +1 -0
- package/dist/inbox/channel-deep-links.js +97 -0
- package/dist/inbox/channel-deep-links.js.map +1 -0
- package/dist/inbox/config.d.ts +7 -0
- package/dist/inbox/config.d.ts.map +1 -0
- package/dist/inbox/config.js +61 -0
- package/dist/inbox/config.js.map +1 -0
- package/dist/inbox/email-curation.d.ts +174 -0
- package/dist/inbox/email-curation.d.ts.map +1 -0
- package/dist/inbox/email-curation.js +1056 -0
- package/dist/inbox/email-curation.js.map +1 -0
- package/dist/inbox/email-unsubscribe-types.d.ts +71 -0
- package/dist/inbox/email-unsubscribe-types.d.ts.map +1 -0
- package/dist/inbox/email-unsubscribe-types.js +1 -0
- package/dist/inbox/email-unsubscribe-types.js.map +1 -0
- package/dist/inbox/gmail-normalize.d.ts +99 -0
- package/dist/inbox/gmail-normalize.d.ts.map +1 -0
- package/dist/inbox/gmail-normalize.js +937 -0
- package/dist/inbox/gmail-normalize.js.map +1 -0
- package/dist/inbox/google-gmail-seam.d.ts +52 -0
- package/dist/inbox/google-gmail-seam.d.ts.map +1 -0
- package/dist/inbox/google-gmail-seam.js +263 -0
- package/dist/inbox/google-gmail-seam.js.map +1 -0
- package/dist/inbox/message-fetcher.d.ts +47 -0
- package/dist/inbox/message-fetcher.d.ts.map +1 -0
- package/dist/inbox/message-fetcher.js +461 -0
- package/dist/inbox/message-fetcher.js.map +1 -0
- package/dist/inbox/migration.d.ts +46 -0
- package/dist/inbox/migration.d.ts.map +1 -0
- package/dist/inbox/migration.js +114 -0
- package/dist/inbox/migration.js.map +1 -0
- package/dist/inbox/reflection.d.ts +40 -0
- package/dist/inbox/reflection.d.ts.map +1 -0
- package/dist/inbox/reflection.js +142 -0
- package/dist/inbox/reflection.js.map +1 -0
- package/dist/inbox/repository.d.ts +58 -0
- package/dist/inbox/repository.d.ts.map +1 -0
- package/dist/inbox/repository.js +376 -0
- package/dist/inbox/repository.js.map +1 -0
- package/dist/inbox/service.d.ts +149 -0
- package/dist/inbox/service.d.ts.map +1 -0
- package/dist/inbox/service.js +247 -0
- package/dist/inbox/service.js.map +1 -0
- package/dist/inbox/triage-classifier.d.ts +28 -0
- package/dist/inbox/triage-classifier.d.ts.map +1 -0
- package/dist/inbox/triage-classifier.js +306 -0
- package/dist/inbox/triage-classifier.js.map +1 -0
- package/dist/inbox/types.d.ts +124 -0
- package/dist/inbox/types.d.ts.map +1 -0
- package/dist/inbox/types.js +1 -0
- package/dist/inbox/types.js.map +1 -0
- package/dist/inbox/unsubscribe-repository.d.ts +14 -0
- package/dist/inbox/unsubscribe-repository.d.ts.map +1 -0
- package/dist/inbox/unsubscribe-repository.js +112 -0
- package/dist/inbox/unsubscribe-repository.js.map +1 -0
- package/dist/inbox/unsubscribe-service.d.ts +41 -0
- package/dist/inbox/unsubscribe-service.d.ts.map +1 -0
- package/dist/inbox/unsubscribe-service.js +351 -0
- package/dist/inbox/unsubscribe-service.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +38 -0
- package/dist/plugin.js.map +1 -0
- package/dist/providers/cross-channel-context.d.ts +21 -0
- package/dist/providers/cross-channel-context.d.ts.map +1 -0
- package/dist/providers/cross-channel-context.js +96 -0
- package/dist/providers/cross-channel-context.js.map +1 -0
- package/dist/providers/inbox-triage.d.ts +12 -0
- package/dist/providers/inbox-triage.d.ts.map +1 -0
- package/dist/providers/inbox-triage.js +98 -0
- package/dist/providers/inbox-triage.js.map +1 -0
- package/dist/register-terminal-view.d.ts +15 -0
- package/dist/register-terminal-view.d.ts.map +1 -0
- package/dist/register-terminal-view.js +21 -0
- package/dist/register-terminal-view.js.map +1 -0
- package/dist/register.d.ts +9 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +5 -0
- package/dist/register.js.map +1 -0
- package/dist/types.d.ts +42 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +25 -0
- package/dist/types.js.map +1 -0
- package/dist/views/bundle.js +315 -0
- package/dist/views/bundle.js.map +1 -0
- package/package.json +9 -9
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import {
|
|
3
|
+
executeRawSql,
|
|
4
|
+
parseJsonArray,
|
|
5
|
+
parseJsonRecord,
|
|
6
|
+
sqlBoolean,
|
|
7
|
+
sqlNumber,
|
|
8
|
+
sqlQuote,
|
|
9
|
+
sqlText,
|
|
10
|
+
toBoolean,
|
|
11
|
+
toNumber,
|
|
12
|
+
toText
|
|
13
|
+
} from "../db/sql.js";
|
|
14
|
+
const TRIAGE_CLASSIFICATIONS = /* @__PURE__ */ new Set([
|
|
15
|
+
"ignore",
|
|
16
|
+
"info",
|
|
17
|
+
"notify",
|
|
18
|
+
"needs_reply",
|
|
19
|
+
"urgent"
|
|
20
|
+
]);
|
|
21
|
+
const TRIAGE_URGENCIES = /* @__PURE__ */ new Set(["low", "medium", "high"]);
|
|
22
|
+
const OWNER_ACTIONS = /* @__PURE__ */ new Set([
|
|
23
|
+
"confirmed",
|
|
24
|
+
"reclassified",
|
|
25
|
+
"edited_draft",
|
|
26
|
+
"ignored"
|
|
27
|
+
]);
|
|
28
|
+
function parseTriageClassification(value) {
|
|
29
|
+
const normalized = toText(value).trim();
|
|
30
|
+
if (TRIAGE_CLASSIFICATIONS.has(normalized)) {
|
|
31
|
+
return normalized;
|
|
32
|
+
}
|
|
33
|
+
throw new Error(
|
|
34
|
+
`[InboxRepository] invalid triage classification: ${normalized}`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
function parseTriageUrgency(value) {
|
|
38
|
+
const normalized = toText(value).trim();
|
|
39
|
+
if (TRIAGE_URGENCIES.has(normalized)) {
|
|
40
|
+
return normalized;
|
|
41
|
+
}
|
|
42
|
+
throw new Error(`[InboxRepository] invalid triage urgency: ${normalized}`);
|
|
43
|
+
}
|
|
44
|
+
function parseNullableTriageClassification(value) {
|
|
45
|
+
const normalized = toText(value).trim();
|
|
46
|
+
return normalized ? parseTriageClassification(normalized) : null;
|
|
47
|
+
}
|
|
48
|
+
function parseOwnerAction(value) {
|
|
49
|
+
const normalized = toText(value).trim();
|
|
50
|
+
if (OWNER_ACTIONS.has(normalized)) {
|
|
51
|
+
return normalized;
|
|
52
|
+
}
|
|
53
|
+
throw new Error(`[InboxRepository] invalid owner action: ${normalized}`);
|
|
54
|
+
}
|
|
55
|
+
function parseJsonStringArray(value, label) {
|
|
56
|
+
const entries = parseJsonArray(value);
|
|
57
|
+
const strings = [];
|
|
58
|
+
for (const entry of entries) {
|
|
59
|
+
if (typeof entry !== "string") {
|
|
60
|
+
throw new Error(`[InboxRepository] ${label} must contain strings`);
|
|
61
|
+
}
|
|
62
|
+
strings.push(entry);
|
|
63
|
+
}
|
|
64
|
+
return strings;
|
|
65
|
+
}
|
|
66
|
+
function parseTriageEntry(row) {
|
|
67
|
+
return {
|
|
68
|
+
id: toText(row.id),
|
|
69
|
+
agentId: toText(row.agent_id),
|
|
70
|
+
source: toText(row.source),
|
|
71
|
+
sourceRoomId: toText(row.source_room_id) || null,
|
|
72
|
+
sourceEntityId: toText(row.source_entity_id) || null,
|
|
73
|
+
sourceMessageId: toText(row.source_message_id) || null,
|
|
74
|
+
channelName: toText(row.channel_name),
|
|
75
|
+
channelType: toText(row.channel_type),
|
|
76
|
+
deepLink: toText(row.deep_link) || null,
|
|
77
|
+
classification: parseTriageClassification(row.classification),
|
|
78
|
+
urgency: parseTriageUrgency(row.urgency),
|
|
79
|
+
confidence: toNumber(row.confidence, 0.5),
|
|
80
|
+
snippet: toText(row.snippet),
|
|
81
|
+
senderName: toText(row.sender_name) || null,
|
|
82
|
+
threadContext: row.thread_context ? parseJsonStringArray(row.thread_context, "thread_context") : null,
|
|
83
|
+
triageReasoning: toText(row.triage_reasoning) || null,
|
|
84
|
+
suggestedResponse: toText(row.suggested_response) || null,
|
|
85
|
+
draftResponse: toText(row.draft_response) || null,
|
|
86
|
+
autoReplied: toBoolean(row.auto_replied, false),
|
|
87
|
+
resolved: toBoolean(row.resolved, false),
|
|
88
|
+
resolvedAt: toText(row.resolved_at) || null,
|
|
89
|
+
createdAt: toText(row.created_at),
|
|
90
|
+
updatedAt: toText(row.updated_at)
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function parseTriageExample(row) {
|
|
94
|
+
return {
|
|
95
|
+
id: toText(row.id),
|
|
96
|
+
agentId: toText(row.agent_id),
|
|
97
|
+
source: toText(row.source),
|
|
98
|
+
snippet: toText(row.snippet),
|
|
99
|
+
classification: parseTriageClassification(row.classification),
|
|
100
|
+
ownerAction: parseOwnerAction(row.owner_action),
|
|
101
|
+
ownerClassification: parseNullableTriageClassification(
|
|
102
|
+
row.owner_classification
|
|
103
|
+
),
|
|
104
|
+
contextJson: parseJsonRecord(row.context_json),
|
|
105
|
+
createdAt: toText(row.created_at)
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function newId() {
|
|
109
|
+
return crypto.randomUUID();
|
|
110
|
+
}
|
|
111
|
+
function isoNow() {
|
|
112
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
113
|
+
}
|
|
114
|
+
function sqlJsonArray(value) {
|
|
115
|
+
if (!value || value.length === 0) return "NULL";
|
|
116
|
+
return sqlQuote(JSON.stringify(value));
|
|
117
|
+
}
|
|
118
|
+
class InboxRepository {
|
|
119
|
+
constructor(runtime) {
|
|
120
|
+
this.runtime = runtime;
|
|
121
|
+
}
|
|
122
|
+
runtime;
|
|
123
|
+
get agentId() {
|
|
124
|
+
return this.runtime.agentId;
|
|
125
|
+
}
|
|
126
|
+
// ---- Triage entries ----
|
|
127
|
+
async storeTriage(opts) {
|
|
128
|
+
const id = newId();
|
|
129
|
+
const now = isoNow();
|
|
130
|
+
await executeRawSql(
|
|
131
|
+
this.runtime,
|
|
132
|
+
`INSERT INTO app_inbox.life_inbox_triage_entries (
|
|
133
|
+
id, agent_id, source, source_room_id, source_entity_id, source_message_id,
|
|
134
|
+
channel_name, channel_type, deep_link, classification, urgency, confidence,
|
|
135
|
+
snippet, sender_name, thread_context, triage_reasoning, suggested_response,
|
|
136
|
+
auto_replied, resolved, created_at, updated_at
|
|
137
|
+
) VALUES (
|
|
138
|
+
${sqlText(id)}, ${sqlText(this.agentId)}, ${sqlText(opts.source)},
|
|
139
|
+
${sqlText(opts.sourceRoomId ?? null)}, ${sqlText(opts.sourceEntityId ?? null)},
|
|
140
|
+
${sqlText(opts.sourceMessageId ?? null)}, ${sqlText(opts.channelName)},
|
|
141
|
+
${sqlText(opts.channelType)}, ${sqlText(opts.deepLink ?? null)},
|
|
142
|
+
${sqlText(opts.classification)}, ${sqlText(opts.urgency)},
|
|
143
|
+
${sqlNumber(opts.confidence)}, ${sqlText(opts.snippet)},
|
|
144
|
+
${sqlText(opts.senderName ?? null)}, ${sqlJsonArray(opts.threadContext)},
|
|
145
|
+
${sqlText(opts.triageReasoning ?? null)}, ${sqlText(opts.suggestedResponse ?? null)},
|
|
146
|
+
FALSE, FALSE, ${sqlText(now)}, ${sqlText(now)}
|
|
147
|
+
)`
|
|
148
|
+
);
|
|
149
|
+
return {
|
|
150
|
+
id,
|
|
151
|
+
agentId: this.agentId,
|
|
152
|
+
source: opts.source,
|
|
153
|
+
sourceRoomId: opts.sourceRoomId ?? null,
|
|
154
|
+
sourceEntityId: opts.sourceEntityId ?? null,
|
|
155
|
+
sourceMessageId: opts.sourceMessageId ?? null,
|
|
156
|
+
channelName: opts.channelName,
|
|
157
|
+
channelType: opts.channelType,
|
|
158
|
+
deepLink: opts.deepLink ?? null,
|
|
159
|
+
classification: opts.classification,
|
|
160
|
+
urgency: opts.urgency,
|
|
161
|
+
confidence: opts.confidence,
|
|
162
|
+
snippet: opts.snippet,
|
|
163
|
+
senderName: opts.senderName ?? null,
|
|
164
|
+
threadContext: opts.threadContext ?? null,
|
|
165
|
+
triageReasoning: opts.triageReasoning ?? null,
|
|
166
|
+
suggestedResponse: opts.suggestedResponse ?? null,
|
|
167
|
+
draftResponse: null,
|
|
168
|
+
autoReplied: false,
|
|
169
|
+
resolved: false,
|
|
170
|
+
resolvedAt: null,
|
|
171
|
+
createdAt: now,
|
|
172
|
+
updatedAt: now
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
async getUnresolved(opts) {
|
|
176
|
+
const limit = opts?.limit ?? 50;
|
|
177
|
+
const rows = await executeRawSql(
|
|
178
|
+
this.runtime,
|
|
179
|
+
`SELECT * FROM app_inbox.life_inbox_triage_entries
|
|
180
|
+
WHERE agent_id = ${sqlText(this.agentId)}
|
|
181
|
+
AND resolved = FALSE
|
|
182
|
+
ORDER BY
|
|
183
|
+
CASE urgency WHEN 'high' THEN 0 WHEN 'medium' THEN 1 ELSE 2 END,
|
|
184
|
+
created_at DESC
|
|
185
|
+
LIMIT ${limit}`
|
|
186
|
+
);
|
|
187
|
+
return rows.map(parseTriageEntry);
|
|
188
|
+
}
|
|
189
|
+
async getUnresolvedForSender(opts) {
|
|
190
|
+
const limit = opts.limit ?? 50;
|
|
191
|
+
const clauses = [`agent_id = ${sqlText(this.agentId)}`, "resolved = FALSE"];
|
|
192
|
+
if (opts.excludeSource) {
|
|
193
|
+
clauses.push(`source != ${sqlText(opts.excludeSource)}`);
|
|
194
|
+
}
|
|
195
|
+
const senderClauses = [];
|
|
196
|
+
if (opts.sourceEntityId) {
|
|
197
|
+
senderClauses.push(`source_entity_id = ${sqlText(opts.sourceEntityId)}`);
|
|
198
|
+
}
|
|
199
|
+
if (opts.senderName) {
|
|
200
|
+
const normalized = opts.senderName.trim().toLowerCase();
|
|
201
|
+
if (normalized) {
|
|
202
|
+
senderClauses.push(
|
|
203
|
+
`(LOWER(sender_name) LIKE ${sqlText(`%${normalized}%`)} OR ${sqlText(normalized)} LIKE '%' || LOWER(sender_name) || '%')`
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (senderClauses.length === 0) return [];
|
|
208
|
+
clauses.push(`(${senderClauses.join(" OR ")})`);
|
|
209
|
+
const rows = await executeRawSql(
|
|
210
|
+
this.runtime,
|
|
211
|
+
`SELECT * FROM app_inbox.life_inbox_triage_entries
|
|
212
|
+
WHERE ${clauses.join("\n AND ")}
|
|
213
|
+
ORDER BY
|
|
214
|
+
CASE urgency WHEN 'high' THEN 0 WHEN 'medium' THEN 1 ELSE 2 END,
|
|
215
|
+
created_at DESC
|
|
216
|
+
LIMIT ${limit}`
|
|
217
|
+
);
|
|
218
|
+
return rows.map(parseTriageEntry);
|
|
219
|
+
}
|
|
220
|
+
async getByClassification(classification, opts) {
|
|
221
|
+
const limit = opts?.limit ?? 50;
|
|
222
|
+
const unresolvedOnly = opts?.unresolvedOnly !== false;
|
|
223
|
+
const resolvedClause = unresolvedOnly ? "AND resolved = FALSE" : "";
|
|
224
|
+
const rows = await executeRawSql(
|
|
225
|
+
this.runtime,
|
|
226
|
+
`SELECT * FROM app_inbox.life_inbox_triage_entries
|
|
227
|
+
WHERE agent_id = ${sqlText(this.agentId)}
|
|
228
|
+
AND classification = ${sqlText(classification)}
|
|
229
|
+
${resolvedClause}
|
|
230
|
+
ORDER BY created_at DESC
|
|
231
|
+
LIMIT ${limit}`
|
|
232
|
+
);
|
|
233
|
+
return rows.map(parseTriageEntry);
|
|
234
|
+
}
|
|
235
|
+
async getById(id) {
|
|
236
|
+
const rows = await executeRawSql(
|
|
237
|
+
this.runtime,
|
|
238
|
+
`SELECT * FROM app_inbox.life_inbox_triage_entries
|
|
239
|
+
WHERE id = ${sqlText(id)} AND agent_id = ${sqlText(this.agentId)}
|
|
240
|
+
LIMIT 1`
|
|
241
|
+
);
|
|
242
|
+
const row = rows[0];
|
|
243
|
+
return row ? parseTriageEntry(row) : null;
|
|
244
|
+
}
|
|
245
|
+
async getBySourceMessageId(sourceMessageId) {
|
|
246
|
+
const rows = await executeRawSql(
|
|
247
|
+
this.runtime,
|
|
248
|
+
`SELECT * FROM app_inbox.life_inbox_triage_entries
|
|
249
|
+
WHERE source_message_id = ${sqlText(sourceMessageId)}
|
|
250
|
+
AND agent_id = ${sqlText(this.agentId)}
|
|
251
|
+
LIMIT 1`
|
|
252
|
+
);
|
|
253
|
+
const row = rows[0];
|
|
254
|
+
return row ? parseTriageEntry(row) : null;
|
|
255
|
+
}
|
|
256
|
+
async getBySourceMessageIds(sourceMessageIds) {
|
|
257
|
+
if (sourceMessageIds.length === 0) return /* @__PURE__ */ new Set();
|
|
258
|
+
const inClause = sourceMessageIds.map((id) => sqlText(id)).join(", ");
|
|
259
|
+
const rows = await executeRawSql(
|
|
260
|
+
this.runtime,
|
|
261
|
+
`SELECT source_message_id FROM app_inbox.life_inbox_triage_entries
|
|
262
|
+
WHERE agent_id = ${sqlText(this.agentId)}
|
|
263
|
+
AND source_message_id IN (${inClause})`
|
|
264
|
+
);
|
|
265
|
+
return new Set(rows.map((r) => toText(r.source_message_id)));
|
|
266
|
+
}
|
|
267
|
+
async markResolved(id, opts) {
|
|
268
|
+
const now = isoNow();
|
|
269
|
+
const sets = [
|
|
270
|
+
`resolved = TRUE`,
|
|
271
|
+
`resolved_at = ${sqlText(now)}`,
|
|
272
|
+
`updated_at = ${sqlText(now)}`
|
|
273
|
+
];
|
|
274
|
+
if (opts?.draftResponse !== void 0) {
|
|
275
|
+
sets.push(`draft_response = ${sqlText(opts.draftResponse)}`);
|
|
276
|
+
}
|
|
277
|
+
if (opts?.autoReplied !== void 0) {
|
|
278
|
+
sets.push(`auto_replied = ${sqlBoolean(opts.autoReplied)}`);
|
|
279
|
+
}
|
|
280
|
+
await executeRawSql(
|
|
281
|
+
this.runtime,
|
|
282
|
+
`UPDATE app_inbox.life_inbox_triage_entries
|
|
283
|
+
SET ${sets.join(", ")}
|
|
284
|
+
WHERE id = ${sqlText(id)} AND agent_id = ${sqlText(this.agentId)}`
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
async getRecentForDigest(sinceIso) {
|
|
288
|
+
const rows = await executeRawSql(
|
|
289
|
+
this.runtime,
|
|
290
|
+
`SELECT * FROM app_inbox.life_inbox_triage_entries
|
|
291
|
+
WHERE agent_id = ${sqlText(this.agentId)}
|
|
292
|
+
AND created_at >= ${sqlText(sinceIso)}
|
|
293
|
+
AND classification != 'ignore'
|
|
294
|
+
ORDER BY
|
|
295
|
+
CASE urgency WHEN 'high' THEN 0 WHEN 'medium' THEN 1 ELSE 2 END,
|
|
296
|
+
created_at DESC`
|
|
297
|
+
);
|
|
298
|
+
return rows.map(parseTriageEntry);
|
|
299
|
+
}
|
|
300
|
+
async getRecentAutoReplies(limit = 5) {
|
|
301
|
+
const rows = await executeRawSql(
|
|
302
|
+
this.runtime,
|
|
303
|
+
`SELECT * FROM app_inbox.life_inbox_triage_entries
|
|
304
|
+
WHERE agent_id = ${sqlText(this.agentId)}
|
|
305
|
+
AND auto_replied = TRUE
|
|
306
|
+
ORDER BY created_at DESC
|
|
307
|
+
LIMIT ${limit}`
|
|
308
|
+
);
|
|
309
|
+
return rows.map(parseTriageEntry);
|
|
310
|
+
}
|
|
311
|
+
async countAutoRepliesSince(sinceIso) {
|
|
312
|
+
const rows = await executeRawSql(
|
|
313
|
+
this.runtime,
|
|
314
|
+
`SELECT COUNT(*) AS cnt FROM app_inbox.life_inbox_triage_entries
|
|
315
|
+
WHERE agent_id = ${sqlText(this.agentId)}
|
|
316
|
+
AND auto_replied = TRUE
|
|
317
|
+
AND created_at >= ${sqlText(sinceIso)}`
|
|
318
|
+
);
|
|
319
|
+
return toNumber(rows[0]?.cnt, 0);
|
|
320
|
+
}
|
|
321
|
+
async cleanupOlderThan(olderThanIso) {
|
|
322
|
+
const rows = await executeRawSql(
|
|
323
|
+
this.runtime,
|
|
324
|
+
`DELETE FROM app_inbox.life_inbox_triage_entries
|
|
325
|
+
WHERE agent_id = ${sqlText(this.agentId)}
|
|
326
|
+
AND resolved = TRUE
|
|
327
|
+
AND created_at < ${sqlText(olderThanIso)}
|
|
328
|
+
RETURNING id`
|
|
329
|
+
);
|
|
330
|
+
return rows.length;
|
|
331
|
+
}
|
|
332
|
+
// ---- Few-shot examples ----
|
|
333
|
+
async storeExample(opts) {
|
|
334
|
+
const id = newId();
|
|
335
|
+
const now = isoNow();
|
|
336
|
+
const contextJson = opts.contextJson ?? {};
|
|
337
|
+
const contextStr = JSON.stringify(contextJson);
|
|
338
|
+
await executeRawSql(
|
|
339
|
+
this.runtime,
|
|
340
|
+
`INSERT INTO app_inbox.life_inbox_triage_examples (
|
|
341
|
+
id, agent_id, source, snippet, classification, owner_action,
|
|
342
|
+
owner_classification, context_json, created_at
|
|
343
|
+
) VALUES (
|
|
344
|
+
${sqlText(id)}, ${sqlText(this.agentId)}, ${sqlText(opts.source)},
|
|
345
|
+
${sqlText(opts.snippet)}, ${sqlText(opts.classification)},
|
|
346
|
+
${sqlText(opts.ownerAction)}, ${sqlText(opts.ownerClassification ?? null)},
|
|
347
|
+
${sqlText(contextStr)}, ${sqlText(now)}
|
|
348
|
+
)`
|
|
349
|
+
);
|
|
350
|
+
return {
|
|
351
|
+
id,
|
|
352
|
+
agentId: this.agentId,
|
|
353
|
+
source: opts.source,
|
|
354
|
+
snippet: opts.snippet,
|
|
355
|
+
classification: opts.classification,
|
|
356
|
+
ownerAction: opts.ownerAction,
|
|
357
|
+
ownerClassification: opts.ownerClassification ?? null,
|
|
358
|
+
contextJson,
|
|
359
|
+
createdAt: now
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
async getExamples(limit = 10) {
|
|
363
|
+
const rows = await executeRawSql(
|
|
364
|
+
this.runtime,
|
|
365
|
+
`SELECT * FROM app_inbox.life_inbox_triage_examples
|
|
366
|
+
WHERE agent_id = ${sqlText(this.agentId)}
|
|
367
|
+
ORDER BY created_at DESC
|
|
368
|
+
LIMIT ${limit}`
|
|
369
|
+
);
|
|
370
|
+
return rows.map(parseTriageExample);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
export {
|
|
374
|
+
InboxRepository
|
|
375
|
+
};
|
|
376
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/inbox/repository.ts"],"sourcesContent":["import crypto from \"node:crypto\";\nimport type { IAgentRuntime } from \"@elizaos/core\";\nimport {\n executeRawSql,\n parseJsonArray,\n parseJsonRecord,\n sqlBoolean,\n sqlNumber,\n sqlQuote,\n sqlText,\n toBoolean,\n toNumber,\n toText,\n} from \"../db/sql.js\";\nimport type {\n OwnerAction,\n TriageClassification,\n TriageEntry,\n TriageExample,\n TriageUrgency,\n} from \"./types.js\";\n\nconst TRIAGE_CLASSIFICATIONS = new Set<TriageClassification>([\n \"ignore\",\n \"info\",\n \"notify\",\n \"needs_reply\",\n \"urgent\",\n]);\n\nconst TRIAGE_URGENCIES = new Set<TriageUrgency>([\"low\", \"medium\", \"high\"]);\n\nconst OWNER_ACTIONS = new Set<OwnerAction>([\n \"confirmed\",\n \"reclassified\",\n \"edited_draft\",\n \"ignored\",\n]);\n\n// ---------------------------------------------------------------------------\n// Row parsing\n// ---------------------------------------------------------------------------\n\nfunction parseTriageClassification(value: unknown): TriageClassification {\n const normalized = toText(value).trim();\n if (TRIAGE_CLASSIFICATIONS.has(normalized as TriageClassification)) {\n return normalized as TriageClassification;\n }\n throw new Error(\n `[InboxRepository] invalid triage classification: ${normalized}`,\n );\n}\n\nfunction parseTriageUrgency(value: unknown): TriageUrgency {\n const normalized = toText(value).trim();\n if (TRIAGE_URGENCIES.has(normalized as TriageUrgency)) {\n return normalized as TriageUrgency;\n }\n throw new Error(`[InboxRepository] invalid triage urgency: ${normalized}`);\n}\n\nfunction parseNullableTriageClassification(\n value: unknown,\n): TriageClassification | null {\n const normalized = toText(value).trim();\n return normalized ? parseTriageClassification(normalized) : null;\n}\n\nfunction parseOwnerAction(value: unknown): OwnerAction {\n const normalized = toText(value).trim();\n if (OWNER_ACTIONS.has(normalized as OwnerAction)) {\n return normalized as OwnerAction;\n }\n throw new Error(`[InboxRepository] invalid owner action: ${normalized}`);\n}\n\nfunction parseJsonStringArray(value: unknown, label: string): string[] {\n const entries = parseJsonArray<unknown>(value);\n const strings: string[] = [];\n for (const entry of entries) {\n if (typeof entry !== \"string\") {\n throw new Error(`[InboxRepository] ${label} must contain strings`);\n }\n strings.push(entry);\n }\n return strings;\n}\n\nfunction parseTriageEntry(row: Record<string, unknown>): TriageEntry {\n return {\n id: toText(row.id),\n agentId: toText(row.agent_id),\n source: toText(row.source),\n sourceRoomId: toText(row.source_room_id) || null,\n sourceEntityId: toText(row.source_entity_id) || null,\n sourceMessageId: toText(row.source_message_id) || null,\n channelName: toText(row.channel_name),\n channelType: toText(row.channel_type),\n deepLink: toText(row.deep_link) || null,\n classification: parseTriageClassification(row.classification),\n urgency: parseTriageUrgency(row.urgency),\n confidence: toNumber(row.confidence, 0.5),\n snippet: toText(row.snippet),\n senderName: toText(row.sender_name) || null,\n threadContext: row.thread_context\n ? parseJsonStringArray(row.thread_context, \"thread_context\")\n : null,\n triageReasoning: toText(row.triage_reasoning) || null,\n suggestedResponse: toText(row.suggested_response) || null,\n draftResponse: toText(row.draft_response) || null,\n autoReplied: toBoolean(row.auto_replied, false),\n resolved: toBoolean(row.resolved, false),\n resolvedAt: toText(row.resolved_at) || null,\n createdAt: toText(row.created_at),\n updatedAt: toText(row.updated_at),\n };\n}\n\nfunction parseTriageExample(row: Record<string, unknown>): TriageExample {\n return {\n id: toText(row.id),\n agentId: toText(row.agent_id),\n source: toText(row.source),\n snippet: toText(row.snippet),\n classification: parseTriageClassification(row.classification),\n ownerAction: parseOwnerAction(row.owner_action),\n ownerClassification: parseNullableTriageClassification(\n row.owner_classification,\n ),\n contextJson: parseJsonRecord(row.context_json),\n createdAt: toText(row.created_at),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction newId(): string {\n return crypto.randomUUID();\n}\n\nfunction isoNow(): string {\n return new Date().toISOString();\n}\n\nfunction sqlJsonArray(value: string[] | null | undefined): string {\n if (!value || value.length === 0) return \"NULL\";\n return sqlQuote(JSON.stringify(value));\n}\n\n// ---------------------------------------------------------------------------\n// Repository\n//\n// Reads/writes the cross-channel triage tables that remain registered by\n// @elizaos/plugin-personal-assistant (`app_inbox.life_inbox_triage_entries`\n// and `_examples`). The tables are inbox-domain but PA owns their migration; we\n// read them directly via the runtime DB handle so this plugin carries no PA\n// dependency. See README for the schema-ownership decision.\n// ---------------------------------------------------------------------------\n\nexport class InboxRepository {\n constructor(private runtime: IAgentRuntime) {}\n\n private get agentId(): string {\n return this.runtime.agentId;\n }\n\n // ---- Triage entries ----\n\n async storeTriage(opts: {\n source: string;\n sourceRoomId?: string;\n sourceEntityId?: string;\n sourceMessageId?: string;\n channelName: string;\n channelType: string;\n deepLink?: string;\n classification: TriageClassification;\n urgency: TriageUrgency;\n confidence: number;\n snippet: string;\n senderName?: string;\n threadContext?: string[];\n triageReasoning?: string;\n suggestedResponse?: string;\n }): Promise<TriageEntry> {\n const id = newId();\n const now = isoNow();\n\n await executeRawSql(\n this.runtime,\n `INSERT INTO app_inbox.life_inbox_triage_entries (\n id, agent_id, source, source_room_id, source_entity_id, source_message_id,\n channel_name, channel_type, deep_link, classification, urgency, confidence,\n snippet, sender_name, thread_context, triage_reasoning, suggested_response,\n auto_replied, resolved, created_at, updated_at\n ) VALUES (\n ${sqlText(id)}, ${sqlText(this.agentId)}, ${sqlText(opts.source)},\n ${sqlText(opts.sourceRoomId ?? null)}, ${sqlText(opts.sourceEntityId ?? null)},\n ${sqlText(opts.sourceMessageId ?? null)}, ${sqlText(opts.channelName)},\n ${sqlText(opts.channelType)}, ${sqlText(opts.deepLink ?? null)},\n ${sqlText(opts.classification)}, ${sqlText(opts.urgency)},\n ${sqlNumber(opts.confidence)}, ${sqlText(opts.snippet)},\n ${sqlText(opts.senderName ?? null)}, ${sqlJsonArray(opts.threadContext)},\n ${sqlText(opts.triageReasoning ?? null)}, ${sqlText(opts.suggestedResponse ?? null)},\n FALSE, FALSE, ${sqlText(now)}, ${sqlText(now)}\n )`,\n );\n\n return {\n id,\n agentId: this.agentId,\n source: opts.source,\n sourceRoomId: opts.sourceRoomId ?? null,\n sourceEntityId: opts.sourceEntityId ?? null,\n sourceMessageId: opts.sourceMessageId ?? null,\n channelName: opts.channelName,\n channelType: opts.channelType,\n deepLink: opts.deepLink ?? null,\n classification: opts.classification,\n urgency: opts.urgency,\n confidence: opts.confidence,\n snippet: opts.snippet,\n senderName: opts.senderName ?? null,\n threadContext: opts.threadContext ?? null,\n triageReasoning: opts.triageReasoning ?? null,\n suggestedResponse: opts.suggestedResponse ?? null,\n draftResponse: null,\n autoReplied: false,\n resolved: false,\n resolvedAt: null,\n createdAt: now,\n updatedAt: now,\n };\n }\n\n async getUnresolved(opts?: { limit?: number }): Promise<TriageEntry[]> {\n const limit = opts?.limit ?? 50;\n const rows = await executeRawSql(\n this.runtime,\n `SELECT * FROM app_inbox.life_inbox_triage_entries\n WHERE agent_id = ${sqlText(this.agentId)}\n AND resolved = FALSE\n ORDER BY\n CASE urgency WHEN 'high' THEN 0 WHEN 'medium' THEN 1 ELSE 2 END,\n created_at DESC\n LIMIT ${limit}`,\n );\n return rows.map(parseTriageEntry);\n }\n\n async getUnresolvedForSender(opts: {\n sourceEntityId?: string | null;\n senderName?: string | null;\n excludeSource?: string | null;\n limit?: number;\n }): Promise<TriageEntry[]> {\n const limit = opts.limit ?? 50;\n const clauses = [`agent_id = ${sqlText(this.agentId)}`, \"resolved = FALSE\"];\n\n if (opts.excludeSource) {\n clauses.push(`source != ${sqlText(opts.excludeSource)}`);\n }\n\n const senderClauses: string[] = [];\n if (opts.sourceEntityId) {\n senderClauses.push(`source_entity_id = ${sqlText(opts.sourceEntityId)}`);\n }\n if (opts.senderName) {\n const normalized = opts.senderName.trim().toLowerCase();\n if (normalized) {\n senderClauses.push(\n `(LOWER(sender_name) LIKE ${sqlText(`%${normalized}%`)} OR ${sqlText(normalized)} LIKE '%' || LOWER(sender_name) || '%')`,\n );\n }\n }\n\n if (senderClauses.length === 0) return [];\n clauses.push(`(${senderClauses.join(\" OR \")})`);\n\n const rows = await executeRawSql(\n this.runtime,\n `SELECT * FROM app_inbox.life_inbox_triage_entries\n WHERE ${clauses.join(\"\\n AND \")}\n ORDER BY\n CASE urgency WHEN 'high' THEN 0 WHEN 'medium' THEN 1 ELSE 2 END,\n created_at DESC\n LIMIT ${limit}`,\n );\n return rows.map(parseTriageEntry);\n }\n\n async getByClassification(\n classification: TriageClassification,\n opts?: { limit?: number; unresolvedOnly?: boolean },\n ): Promise<TriageEntry[]> {\n const limit = opts?.limit ?? 50;\n const unresolvedOnly = opts?.unresolvedOnly !== false;\n const resolvedClause = unresolvedOnly ? \"AND resolved = FALSE\" : \"\";\n const rows = await executeRawSql(\n this.runtime,\n `SELECT * FROM app_inbox.life_inbox_triage_entries\n WHERE agent_id = ${sqlText(this.agentId)}\n AND classification = ${sqlText(classification)}\n ${resolvedClause}\n ORDER BY created_at DESC\n LIMIT ${limit}`,\n );\n return rows.map(parseTriageEntry);\n }\n\n async getById(id: string): Promise<TriageEntry | null> {\n const rows = await executeRawSql(\n this.runtime,\n `SELECT * FROM app_inbox.life_inbox_triage_entries\n WHERE id = ${sqlText(id)} AND agent_id = ${sqlText(this.agentId)}\n LIMIT 1`,\n );\n const row = rows[0];\n return row ? parseTriageEntry(row) : null;\n }\n\n async getBySourceMessageId(\n sourceMessageId: string,\n ): Promise<TriageEntry | null> {\n const rows = await executeRawSql(\n this.runtime,\n `SELECT * FROM app_inbox.life_inbox_triage_entries\n WHERE source_message_id = ${sqlText(sourceMessageId)}\n AND agent_id = ${sqlText(this.agentId)}\n LIMIT 1`,\n );\n const row = rows[0];\n return row ? parseTriageEntry(row) : null;\n }\n\n async getBySourceMessageIds(\n sourceMessageIds: string[],\n ): Promise<Set<string>> {\n if (sourceMessageIds.length === 0) return new Set();\n const inClause = sourceMessageIds.map((id) => sqlText(id)).join(\", \");\n const rows = await executeRawSql(\n this.runtime,\n `SELECT source_message_id FROM app_inbox.life_inbox_triage_entries\n WHERE agent_id = ${sqlText(this.agentId)}\n AND source_message_id IN (${inClause})`,\n );\n return new Set(rows.map((r) => toText(r.source_message_id)));\n }\n\n async markResolved(\n id: string,\n opts?: { draftResponse?: string; autoReplied?: boolean },\n ): Promise<void> {\n const now = isoNow();\n const sets = [\n `resolved = TRUE`,\n `resolved_at = ${sqlText(now)}`,\n `updated_at = ${sqlText(now)}`,\n ];\n if (opts?.draftResponse !== undefined) {\n sets.push(`draft_response = ${sqlText(opts.draftResponse)}`);\n }\n if (opts?.autoReplied !== undefined) {\n sets.push(`auto_replied = ${sqlBoolean(opts.autoReplied)}`);\n }\n await executeRawSql(\n this.runtime,\n `UPDATE app_inbox.life_inbox_triage_entries\n SET ${sets.join(\", \")}\n WHERE id = ${sqlText(id)} AND agent_id = ${sqlText(this.agentId)}`,\n );\n }\n\n async getRecentForDigest(sinceIso: string): Promise<TriageEntry[]> {\n const rows = await executeRawSql(\n this.runtime,\n `SELECT * FROM app_inbox.life_inbox_triage_entries\n WHERE agent_id = ${sqlText(this.agentId)}\n AND created_at >= ${sqlText(sinceIso)}\n AND classification != 'ignore'\n ORDER BY\n CASE urgency WHEN 'high' THEN 0 WHEN 'medium' THEN 1 ELSE 2 END,\n created_at DESC`,\n );\n return rows.map(parseTriageEntry);\n }\n\n async getRecentAutoReplies(limit = 5): Promise<TriageEntry[]> {\n const rows = await executeRawSql(\n this.runtime,\n `SELECT * FROM app_inbox.life_inbox_triage_entries\n WHERE agent_id = ${sqlText(this.agentId)}\n AND auto_replied = TRUE\n ORDER BY created_at DESC\n LIMIT ${limit}`,\n );\n return rows.map(parseTriageEntry);\n }\n\n async countAutoRepliesSince(sinceIso: string): Promise<number> {\n const rows = await executeRawSql(\n this.runtime,\n `SELECT COUNT(*) AS cnt FROM app_inbox.life_inbox_triage_entries\n WHERE agent_id = ${sqlText(this.agentId)}\n AND auto_replied = TRUE\n AND created_at >= ${sqlText(sinceIso)}`,\n );\n return toNumber(rows[0]?.cnt, 0);\n }\n\n async cleanupOlderThan(olderThanIso: string): Promise<number> {\n const rows = await executeRawSql(\n this.runtime,\n `DELETE FROM app_inbox.life_inbox_triage_entries\n WHERE agent_id = ${sqlText(this.agentId)}\n AND resolved = TRUE\n AND created_at < ${sqlText(olderThanIso)}\n RETURNING id`,\n );\n return rows.length;\n }\n\n // ---- Few-shot examples ----\n\n async storeExample(opts: {\n source: string;\n snippet: string;\n classification: TriageClassification;\n ownerAction: OwnerAction;\n ownerClassification?: TriageClassification;\n contextJson?: Record<string, unknown>;\n }): Promise<TriageExample> {\n const id = newId();\n const now = isoNow();\n const contextJson = opts.contextJson ?? {};\n const contextStr = JSON.stringify(contextJson);\n\n await executeRawSql(\n this.runtime,\n `INSERT INTO app_inbox.life_inbox_triage_examples (\n id, agent_id, source, snippet, classification, owner_action,\n owner_classification, context_json, created_at\n ) VALUES (\n ${sqlText(id)}, ${sqlText(this.agentId)}, ${sqlText(opts.source)},\n ${sqlText(opts.snippet)}, ${sqlText(opts.classification)},\n ${sqlText(opts.ownerAction)}, ${sqlText(opts.ownerClassification ?? null)},\n ${sqlText(contextStr)}, ${sqlText(now)}\n )`,\n );\n\n return {\n id,\n agentId: this.agentId,\n source: opts.source,\n snippet: opts.snippet,\n classification: opts.classification,\n ownerAction: opts.ownerAction,\n ownerClassification: opts.ownerClassification ?? null,\n contextJson,\n createdAt: now,\n };\n }\n\n async getExamples(limit = 10): Promise<TriageExample[]> {\n const rows = await executeRawSql(\n this.runtime,\n `SELECT * FROM app_inbox.life_inbox_triage_examples\n WHERE agent_id = ${sqlText(this.agentId)}\n ORDER BY created_at DESC\n LIMIT ${limit}`,\n );\n return rows.map(parseTriageExample);\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InboxService — the inbox triage back-end.
|
|
3
|
+
*
|
|
4
|
+
* Standalone successor to the inbox-domain logic that lived in PA's
|
|
5
|
+
* `service-mixin-inbox` + `inbox/` modules. It holds its own runtime and
|
|
6
|
+
* {@link InboxRepository} (raw SQL over the `app_inbox.life_inbox_triage_*`
|
|
7
|
+
* tables PA still registers), classifies inbound messages with the LLM, and
|
|
8
|
+
* answers the triage-queue reads the INBOX action and inboxTriage provider need.
|
|
9
|
+
* It carries no dependency on `@elizaos/plugin-personal-assistant`.
|
|
10
|
+
*
|
|
11
|
+
* NOT here (delegated / left in PA, by design):
|
|
12
|
+
* - `getInbox` / `markInboxEntryRead` — the cached cross-channel inbox that
|
|
13
|
+
* backs `GET /api/lifeops/inbox`. It is coupled to PA's `LifeOpsRepository`
|
|
14
|
+
* inbox cache, LLM priority scoring, Gmail/X connector sources, and the
|
|
15
|
+
* app-state store, so it remains a PA service method (the route shape stays
|
|
16
|
+
* byte-identical). InboxService takes the inbound feed as input instead of
|
|
17
|
+
* pulling connectors itself.
|
|
18
|
+
*/
|
|
19
|
+
import type { IAgentRuntime } from "@elizaos/core";
|
|
20
|
+
import { type CurationDecision, type EmailCurationIdentityHook, type EmailCurationOutput, type EmailCurationPolicy, type EmailCurationPolicyHook } from "./email-curation.js";
|
|
21
|
+
import { InboxRepository } from "./repository.js";
|
|
22
|
+
import type { InboundMessage, InboxTriageConfig, TriageClassification, TriageEntry } from "./types.js";
|
|
23
|
+
export interface TriageOptions {
|
|
24
|
+
/** Override the loaded triage config (priority senders/channels, rules). */
|
|
25
|
+
config?: InboxTriageConfig;
|
|
26
|
+
/** Owner context string injected into the classifier prompt. */
|
|
27
|
+
ownerContext?: string;
|
|
28
|
+
/** How many past owner-corrected examples to few-shot the classifier with. */
|
|
29
|
+
exampleLimit?: number;
|
|
30
|
+
/** Skip persistence and only return the classification (default false). */
|
|
31
|
+
classifyOnly?: boolean;
|
|
32
|
+
}
|
|
33
|
+
export interface TriagedMessage {
|
|
34
|
+
message: InboundMessage;
|
|
35
|
+
classification: TriageClassification;
|
|
36
|
+
urgency: "low" | "medium" | "high";
|
|
37
|
+
confidence: number;
|
|
38
|
+
reasoning: string;
|
|
39
|
+
suggestedResponse?: string;
|
|
40
|
+
/** The persisted triage entry, unless `classifyOnly` was set. */
|
|
41
|
+
entry?: TriageEntry;
|
|
42
|
+
}
|
|
43
|
+
export interface TriageRunResult {
|
|
44
|
+
triaged: TriagedMessage[];
|
|
45
|
+
}
|
|
46
|
+
export interface SearchOptions {
|
|
47
|
+
classification?: TriageClassification;
|
|
48
|
+
limit?: number;
|
|
49
|
+
unresolvedOnly?: boolean;
|
|
50
|
+
}
|
|
51
|
+
export interface CurateOptions {
|
|
52
|
+
/**
|
|
53
|
+
* Identity resolver. Defaults to a hook backed by the runtime
|
|
54
|
+
* {@link resolveKnowledgeGraphService | knowledge-graph service}, which
|
|
55
|
+
* resolves the sender's entity from the runtime graph. Injectable as a test
|
|
56
|
+
* seam and to let callers override the identity source.
|
|
57
|
+
*/
|
|
58
|
+
identityHook?: EmailCurationIdentityHook;
|
|
59
|
+
/**
|
|
60
|
+
* Policy hook applied after the engine's provisional decision. Defaults to a
|
|
61
|
+
* no-op (the engine's built-in `DEFAULT_POLICY` thresholds and delete
|
|
62
|
+
* blockers still apply). No PA-owned policy store is reachable from the
|
|
63
|
+
* inbox plugin without importing PA, so there is no default policy source
|
|
64
|
+
* beyond the engine's own defaults.
|
|
65
|
+
*/
|
|
66
|
+
policyHook?: EmailCurationPolicyHook;
|
|
67
|
+
/** Static policy overrides merged onto the engine defaults. */
|
|
68
|
+
policy?: EmailCurationPolicy;
|
|
69
|
+
/** Override the curation timestamp (defaults to engine `now`). */
|
|
70
|
+
now?: string;
|
|
71
|
+
}
|
|
72
|
+
/** The curation decision attached to a triaged message. */
|
|
73
|
+
export interface CuratedMessage extends TriagedMessage {
|
|
74
|
+
curation: CurationDecision;
|
|
75
|
+
}
|
|
76
|
+
export interface TriageWithCurationResult {
|
|
77
|
+
triaged: CuratedMessage[];
|
|
78
|
+
curation: EmailCurationOutput;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* The triage / search / list back-end for the inbox domain. One instance per
|
|
82
|
+
* call is fine — the repository is a thin raw-SQL wrapper over the runtime DB.
|
|
83
|
+
*/
|
|
84
|
+
export declare class InboxService {
|
|
85
|
+
private readonly runtime;
|
|
86
|
+
private readonly repository;
|
|
87
|
+
constructor(runtime: IAgentRuntime);
|
|
88
|
+
getRepository(): InboxRepository;
|
|
89
|
+
/**
|
|
90
|
+
* Classify a batch of inbound messages and (unless `classifyOnly`) persist
|
|
91
|
+
* one triage entry per message. Returns the per-message decision in input
|
|
92
|
+
* order. Messages already triaged by `source_message_id` are skipped so a
|
|
93
|
+
* re-run does not double-store.
|
|
94
|
+
*/
|
|
95
|
+
triage(messages: InboundMessage[], opts?: TriageOptions): Promise<TriageRunResult>;
|
|
96
|
+
/**
|
|
97
|
+
* Surface an act-now triage entry (`urgent` / `needs_reply`) on the home
|
|
98
|
+
* notification rail. Best-effort: a runtime with no NotificationService (a
|
|
99
|
+
* headless/test runtime) is a no-op. `info`/`notify`/`ignore` stay in the
|
|
100
|
+
* inbox view without pushing a notification.
|
|
101
|
+
*/
|
|
102
|
+
private notifyAttention;
|
|
103
|
+
/**
|
|
104
|
+
* Run the pure email-curation engine over a batch of inbound messages and
|
|
105
|
+
* return the per-candidate decision (save / archive / delete / review with
|
|
106
|
+
* evidence, citations, and a bulk-review block).
|
|
107
|
+
*
|
|
108
|
+
* This is the richer decision path that complements {@link triage}: triage
|
|
109
|
+
* answers "how urgent is this and should I reply", curation answers "what
|
|
110
|
+
* should happen to this message in the owner's mailbox". It does not persist
|
|
111
|
+
* anything — callers decide what to do with the suggested action.
|
|
112
|
+
*
|
|
113
|
+
* The identity hook is backed by the runtime knowledge-graph service so the
|
|
114
|
+
* sender's entity (VIP / known person / service) feeds the engine's
|
|
115
|
+
* delete-blockers. Both hooks are injectable as a test seam.
|
|
116
|
+
*/
|
|
117
|
+
curate(messages: InboundMessage[], opts?: CurateOptions): Promise<EmailCurationOutput>;
|
|
118
|
+
/**
|
|
119
|
+
* Triage a batch, then attach a curation decision to each message in the
|
|
120
|
+
* same input order. Triage behavior is unchanged (the existing
|
|
121
|
+
* classification + persistence still runs); curation is additive.
|
|
122
|
+
*/
|
|
123
|
+
triageWithCuration(messages: InboundMessage[], opts?: TriageOptions & CurateOptions): Promise<TriageWithCurationResult>;
|
|
124
|
+
/**
|
|
125
|
+
* Build an {@link EmailCurationIdentityHook} backed by the runtime
|
|
126
|
+
* knowledge-graph service. Pre-resolves every candidate's sender against the
|
|
127
|
+
* entity graph (the engine hook itself must be synchronous, so the async
|
|
128
|
+
* graph reads happen here) and maps the resolved entity onto the engine's
|
|
129
|
+
* identity kinds. Candidates the graph cannot resolve fall through to the
|
|
130
|
+
* engine's built-in sender heuristics. When the graph service is absent the
|
|
131
|
+
* hook resolves nothing.
|
|
132
|
+
*/
|
|
133
|
+
private buildKnowledgeGraphIdentityHook;
|
|
134
|
+
/**
|
|
135
|
+
* Read persisted triage entries, optionally filtered by classification.
|
|
136
|
+
* Backs the INBOX action's `search`/`list` reads over the triage queue.
|
|
137
|
+
*/
|
|
138
|
+
search(opts?: SearchOptions): Promise<TriageEntry[]>;
|
|
139
|
+
/** Unresolved triage queue (urgency-ordered). */
|
|
140
|
+
list(limit?: number): Promise<TriageEntry[]>;
|
|
141
|
+
/** Non-ignored triage entries created since `sinceIso`, urgency-ordered. */
|
|
142
|
+
digest(sinceIso: string): Promise<TriageEntry[]>;
|
|
143
|
+
/** Mark a triage entry resolved (optionally recording the sent draft). */
|
|
144
|
+
resolve(id: string, opts?: {
|
|
145
|
+
draftResponse?: string;
|
|
146
|
+
autoReplied?: boolean;
|
|
147
|
+
}): Promise<void>;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/inbox/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAuB,MAAM,eAAe,CAAC;AAIxE,OAAO,EACL,KAAK,gBAAgB,EAGrB,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAE7B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EACZ,MAAM,YAAY,CAAC;AA+CpB,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,cAAc,CAAC;IACxB,cAAc,EAAE,oBAAoB,CAAC;IACrC,OAAO,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iEAAiE;IACjE,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,yBAAyB,CAAC;IACzC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,uBAAuB,CAAC;IACrC,+DAA+D;IAC/D,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,2DAA2D;AAC3D,MAAM,WAAW,cAAe,SAAQ,cAAc;IACpD,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAED;;;GAGG;AACH,qBAAa,YAAY;IAGX,OAAO,CAAC,QAAQ,CAAC,OAAO;IAFpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;gBAEhB,OAAO,EAAE,aAAa;IAInD,aAAa,IAAI,eAAe;IAIhC;;;;;OAKG;IACG,MAAM,CACV,QAAQ,EAAE,cAAc,EAAE,EAC1B,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,eAAe,CAAC;IA2E3B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IA4BvB;;;;;;;;;;;;;OAaG;IACG,MAAM,CACV,QAAQ,EAAE,cAAc,EAAE,EAC1B,IAAI,GAAE,aAAkB,GACvB,OAAO,CAAC,mBAAmB,CAAC;IAkB/B;;;;OAIG;IACG,kBAAkB,CACtB,QAAQ,EAAE,cAAc,EAAE,EAC1B,IAAI,GAAE,aAAa,GAAG,aAAkB,GACvC,OAAO,CAAC,wBAAwB,CAAC;IA2BpC;;;;;;;;OAQG;YACW,+BAA+B;IAsB7C;;;OAGG;IACG,MAAM,CAAC,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAc9D,iDAAiD;IAC3C,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAMlD,4EAA4E;IACtE,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAItD,0EAA0E;IACpE,OAAO,CACX,EAAE,EAAE,MAAM,EACV,IAAI,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,GACvD,OAAO,CAAC,IAAI,CAAC;CAGjB"}
|