@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,96 @@
|
|
|
1
|
+
import { hasOwnerAccess } from "@elizaos/agent/security/access";
|
|
2
|
+
import { logger } from "@elizaos/core";
|
|
3
|
+
import { InboxRepository } from "../inbox/repository.js";
|
|
4
|
+
const EMPTY = { text: "", values: {}, data: {} };
|
|
5
|
+
const MAX_ENTRIES = 8;
|
|
6
|
+
async function resolveSenderLabel(runtime, message) {
|
|
7
|
+
const entityId = typeof message.entityId === "string" && message.entityId.length > 0 ? message.entityId : null;
|
|
8
|
+
let name = null;
|
|
9
|
+
if (entityId) {
|
|
10
|
+
try {
|
|
11
|
+
const entity = await runtime.getEntityById?.(entityId);
|
|
12
|
+
const metaName = entity?.metadata?.name;
|
|
13
|
+
name = entity?.names?.[0] ?? (typeof metaName === "string" ? metaName : null);
|
|
14
|
+
} catch {
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return { entityId, name };
|
|
18
|
+
}
|
|
19
|
+
function matchesSender(entry, entityId, name, currentSource) {
|
|
20
|
+
if (entry.source === currentSource) return false;
|
|
21
|
+
if (entityId && entry.sourceEntityId === entityId) return true;
|
|
22
|
+
if (name && entry.senderName) {
|
|
23
|
+
const needle = name.toLowerCase();
|
|
24
|
+
const haystack = entry.senderName.toLowerCase();
|
|
25
|
+
return haystack.includes(needle) || needle.includes(haystack);
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
function escapeMarkdownText(value) {
|
|
30
|
+
return value.replaceAll("\\", "\\\\").replaceAll("`", "\\`").replaceAll("*", "\\*").replaceAll("_", "\\_").replaceAll("[", "\\[").replaceAll("]", "\\]").replaceAll("(", "\\(").replaceAll(")", "\\)").replaceAll("#", "\\#").replaceAll(">", "\\>").replaceAll("|", "\\|").replaceAll("\n", " ");
|
|
31
|
+
}
|
|
32
|
+
function formatEntry(entry) {
|
|
33
|
+
const when = entry.createdAt ? new Date(entry.createdAt).toISOString().slice(0, 10) : "recently";
|
|
34
|
+
const channelName = escapeMarkdownText(entry.channelName);
|
|
35
|
+
const source = escapeMarkdownText(entry.source);
|
|
36
|
+
const snippet = escapeMarkdownText(entry.snippet.slice(0, 80));
|
|
37
|
+
const tag = entry.classification === "urgent" ? " \u26A0\uFE0F" : "";
|
|
38
|
+
return `- **${channelName}** (${source}, ${when})${tag}: "${snippet}"`;
|
|
39
|
+
}
|
|
40
|
+
const crossChannelContextProvider = {
|
|
41
|
+
name: "inboxCrossChannelContext",
|
|
42
|
+
description: "Injects recent triage entries from the current message sender across other channels. Use when the owner asks about a person or thread \u2014 surfaces cross-channel history automatically.",
|
|
43
|
+
descriptionCompressed: "Current sender's cross-channel triage history (other channels).",
|
|
44
|
+
dynamic: true,
|
|
45
|
+
position: -3,
|
|
46
|
+
contexts: ["messaging", "email", "inbox"],
|
|
47
|
+
contextGate: { anyOf: ["messaging", "email", "inbox"] },
|
|
48
|
+
cacheScope: "turn",
|
|
49
|
+
roleGate: { minRole: "OWNER" },
|
|
50
|
+
async get(runtime, message, _state) {
|
|
51
|
+
if (!await hasOwnerAccess(runtime, message)) return EMPTY;
|
|
52
|
+
const { entityId, name } = await resolveSenderLabel(runtime, message);
|
|
53
|
+
if (!entityId && !name) return EMPTY;
|
|
54
|
+
const currentSource = typeof message.content?.source === "string" ? message.content.source : "";
|
|
55
|
+
let repo;
|
|
56
|
+
try {
|
|
57
|
+
repo = new InboxRepository(runtime);
|
|
58
|
+
} catch {
|
|
59
|
+
return EMPTY;
|
|
60
|
+
}
|
|
61
|
+
let entries;
|
|
62
|
+
try {
|
|
63
|
+
entries = await repo.getUnresolvedForSender({
|
|
64
|
+
sourceEntityId: entityId,
|
|
65
|
+
senderName: name,
|
|
66
|
+
excludeSource: currentSource,
|
|
67
|
+
limit: MAX_ENTRIES
|
|
68
|
+
});
|
|
69
|
+
} catch (error) {
|
|
70
|
+
logger.debug("[cross-channel-context] DB query failed:", String(error));
|
|
71
|
+
return EMPTY;
|
|
72
|
+
}
|
|
73
|
+
const matched = entries.filter(
|
|
74
|
+
(e) => matchesSender(e, entityId, name, currentSource)
|
|
75
|
+
);
|
|
76
|
+
if (matched.length === 0) return EMPTY;
|
|
77
|
+
const senderLabel = escapeMarkdownText(name ?? entityId ?? "this sender");
|
|
78
|
+
const lines = [
|
|
79
|
+
`# ${senderLabel} \u2014 cross-channel activity (${matched.length} threads)`
|
|
80
|
+
];
|
|
81
|
+
for (const entry of matched) {
|
|
82
|
+
lines.push(formatEntry(entry));
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
text: lines.join("\n"),
|
|
86
|
+
values: { crossChannelCount: matched.length },
|
|
87
|
+
data: { entries: matched }
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
var cross_channel_context_default = crossChannelContextProvider;
|
|
92
|
+
export {
|
|
93
|
+
crossChannelContextProvider,
|
|
94
|
+
cross_channel_context_default as default
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=cross-channel-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/providers/cross-channel-context.ts"],"sourcesContent":["/**\n * CROSS_CHANNEL_CONTEXT provider.\n *\n * When the owner is in a conversation, this injects any recent triage entries\n * from the same sender across *other* channels — so if someone DM'd on Discord\n * and also emailed, both threads surface in the same planner turn.\n *\n * Resolution order:\n * 1. Match triage entries by entityId (most precise — UUID identity).\n * 2. Fall back to case-insensitive senderName substring match.\n *\n * Owner-only (same gate as inboxTriage). Silently returns empty when:\n * - the caller is not the owner,\n * - the runtime DB is unavailable,\n * - no sender can be resolved from the current message,\n * - or no cross-channel entries exist for that sender.\n */\n\nimport { hasOwnerAccess } from \"@elizaos/agent/security/access\";\nimport type {\n IAgentRuntime,\n Memory,\n Provider,\n ProviderResult,\n State,\n} from \"@elizaos/core\";\nimport { logger } from \"@elizaos/core\";\nimport { InboxRepository } from \"../inbox/repository.js\";\nimport type { TriageEntry } from \"../inbox/types.js\";\n\nconst EMPTY: ProviderResult = { text: \"\", values: {}, data: {} };\n\nconst MAX_ENTRIES = 8;\n\nasync function resolveSenderLabel(\n runtime: IAgentRuntime,\n message: Memory,\n): Promise<{ entityId: string | null; name: string | null }> {\n const entityId =\n typeof message.entityId === \"string\" && message.entityId.length > 0\n ? message.entityId\n : null;\n\n let name: string | null = null;\n if (entityId) {\n try {\n const entity = await runtime.getEntityById?.(entityId);\n const metaName = entity?.metadata?.name;\n name =\n entity?.names?.[0] ?? (typeof metaName === \"string\" ? metaName : null);\n } catch {\n // entity lookup is best-effort\n }\n }\n\n return { entityId, name };\n}\n\nfunction matchesSender(\n entry: TriageEntry,\n entityId: string | null,\n name: string | null,\n currentSource: string,\n): boolean {\n // Skip entries from the same source — the planner already sees this channel.\n if (entry.source === currentSource) return false;\n\n if (entityId && entry.sourceEntityId === entityId) return true;\n\n if (name && entry.senderName) {\n const needle = name.toLowerCase();\n const haystack = entry.senderName.toLowerCase();\n return haystack.includes(needle) || needle.includes(haystack);\n }\n\n return false;\n}\n\nfunction escapeMarkdownText(value: string): string {\n return value\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll(\"`\", \"\\\\`\")\n .replaceAll(\"*\", \"\\\\*\")\n .replaceAll(\"_\", \"\\\\_\")\n .replaceAll(\"[\", \"\\\\[\")\n .replaceAll(\"]\", \"\\\\]\")\n .replaceAll(\"(\", \"\\\\(\")\n .replaceAll(\")\", \"\\\\)\")\n .replaceAll(\"#\", \"\\\\#\")\n .replaceAll(\">\", \"\\\\>\")\n .replaceAll(\"|\", \"\\\\|\")\n .replaceAll(\"\\n\", \" \");\n}\n\nfunction formatEntry(entry: TriageEntry): string {\n const when = entry.createdAt\n ? new Date(entry.createdAt).toISOString().slice(0, 10)\n : \"recently\";\n const channelName = escapeMarkdownText(entry.channelName);\n const source = escapeMarkdownText(entry.source);\n const snippet = escapeMarkdownText(entry.snippet.slice(0, 80));\n const tag = entry.classification === \"urgent\" ? \" ⚠️\" : \"\";\n return `- **${channelName}** (${source}, ${when})${tag}: \"${snippet}\"`;\n}\n\nexport const crossChannelContextProvider: Provider = {\n name: \"inboxCrossChannelContext\",\n description:\n \"Injects recent triage entries from the current message sender across other channels. \" +\n \"Use when the owner asks about a person or thread — surfaces cross-channel history automatically.\",\n descriptionCompressed:\n \"Current sender's cross-channel triage history (other channels).\",\n dynamic: true,\n position: -3,\n contexts: [\"messaging\", \"email\", \"inbox\"],\n contextGate: { anyOf: [\"messaging\", \"email\", \"inbox\"] },\n cacheScope: \"turn\",\n roleGate: { minRole: \"OWNER\" },\n\n async get(\n runtime: IAgentRuntime,\n message: Memory,\n _state: State,\n ): Promise<ProviderResult> {\n if (!(await hasOwnerAccess(runtime, message))) return EMPTY;\n\n const { entityId, name } = await resolveSenderLabel(runtime, message);\n if (!entityId && !name) return EMPTY;\n\n const currentSource =\n typeof (message.content as { source?: string })?.source === \"string\"\n ? (message.content as { source: string }).source\n : \"\";\n\n let repo: InboxRepository;\n try {\n repo = new InboxRepository(runtime);\n } catch {\n return EMPTY;\n }\n\n let entries: TriageEntry[];\n try {\n entries = await repo.getUnresolvedForSender({\n sourceEntityId: entityId,\n senderName: name,\n excludeSource: currentSource,\n limit: MAX_ENTRIES,\n });\n } catch (error) {\n logger.debug(\"[cross-channel-context] DB query failed:\", String(error));\n return EMPTY;\n }\n\n const matched = entries.filter((e) =>\n matchesSender(e, entityId, name, currentSource),\n );\n\n if (matched.length === 0) return EMPTY;\n\n const senderLabel = escapeMarkdownText(name ?? entityId ?? \"this sender\");\n const lines: string[] = [\n `# ${senderLabel} — cross-channel activity (${matched.length} threads)`,\n ];\n for (const entry of matched) {\n lines.push(formatEntry(entry));\n }\n\n return {\n text: lines.join(\"\\n\"),\n values: { crossChannelCount: matched.length },\n data: { entries: matched },\n };\n },\n};\n\nexport default crossChannelContextProvider;\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Provider } from "@elizaos/core";
|
|
2
|
+
/**
|
|
3
|
+
* inboxTriage provider — injects pending inbox triage items into owner context.
|
|
4
|
+
*
|
|
5
|
+
* Owner-only (`roleGate.minRole: OWNER` + the `hasOwnerAccess` gate below).
|
|
6
|
+
* Because it only ever runs for the owner, the LifeOps egress redaction it used
|
|
7
|
+
* is always a pass-through, so the ported provider surfaces the owner's full
|
|
8
|
+
* triage snippets and deep links — observably identical to the LifeOps version.
|
|
9
|
+
*/
|
|
10
|
+
export declare const inboxTriageProvider: Provider;
|
|
11
|
+
export default inboxTriageProvider;
|
|
12
|
+
//# sourceMappingURL=inbox-triage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox-triage.d.ts","sourceRoot":"","sources":["../../src/providers/inbox-triage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,QAAQ,EAGT,MAAM,eAAe,CAAC;AAWvB;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAiGjC,CAAC;AASF,eAAe,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { hasOwnerAccess } from "@elizaos/agent/security/access";
|
|
2
|
+
import { logger } from "@elizaos/core";
|
|
3
|
+
import { InboxRepository } from "../inbox/repository.js";
|
|
4
|
+
const EMPTY = {
|
|
5
|
+
text: "",
|
|
6
|
+
values: { inboxUnresolved: 0, inboxUrgent: 0 },
|
|
7
|
+
data: {}
|
|
8
|
+
};
|
|
9
|
+
const inboxTriageProvider = {
|
|
10
|
+
name: "inboxTriage",
|
|
11
|
+
description: "Injects pending inbox triage items into owner context. Shows urgent messages, items needing reply, and recent auto-replies across all channels including email. Use MESSAGE action=triage/list_inbox/search_inbox/respond/draft_reply/send_draft for cross-channel triage, digest, respond, Gmail search/read, and Gmail draft/send reply workflows. If the request is Gmail-only, MESSAGE should use source=gmail; if it is just 'my inbox', MESSAGE should use the cross-channel path.",
|
|
12
|
+
descriptionCompressed: "Pending inbox triage items across all channels incl email.",
|
|
13
|
+
dynamic: true,
|
|
14
|
+
position: 14,
|
|
15
|
+
// after lifeops (12), before escalation (15)
|
|
16
|
+
contexts: ["email", "messaging", "tasks"],
|
|
17
|
+
contextGate: { anyOf: ["email", "messaging", "tasks"] },
|
|
18
|
+
cacheScope: "turn",
|
|
19
|
+
roleGate: { minRole: "OWNER" },
|
|
20
|
+
async get(runtime, message, _state) {
|
|
21
|
+
if (!await hasOwnerAccess(runtime, message)) {
|
|
22
|
+
return EMPTY;
|
|
23
|
+
}
|
|
24
|
+
let repo;
|
|
25
|
+
try {
|
|
26
|
+
repo = new InboxRepository(runtime);
|
|
27
|
+
} catch {
|
|
28
|
+
return EMPTY;
|
|
29
|
+
}
|
|
30
|
+
let urgent;
|
|
31
|
+
let needsReply;
|
|
32
|
+
let recentAutoReplies;
|
|
33
|
+
try {
|
|
34
|
+
[urgent, needsReply, recentAutoReplies] = await Promise.all([
|
|
35
|
+
repo.getByClassification("urgent", { limit: 5 }),
|
|
36
|
+
repo.getByClassification("needs_reply", { limit: 10 }),
|
|
37
|
+
repo.getRecentAutoReplies(5)
|
|
38
|
+
]);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
logger.debug(
|
|
41
|
+
"[inbox-triage-provider] DB query failed (schema may not exist yet):",
|
|
42
|
+
String(error)
|
|
43
|
+
);
|
|
44
|
+
return EMPTY;
|
|
45
|
+
}
|
|
46
|
+
const unresolved = urgent.length + needsReply.length;
|
|
47
|
+
if (unresolved === 0 && recentAutoReplies.length === 0) {
|
|
48
|
+
return EMPTY;
|
|
49
|
+
}
|
|
50
|
+
const lines = [`# Inbox: ${unresolved} items pending`];
|
|
51
|
+
if (urgent.length > 0) {
|
|
52
|
+
lines.push("\n## Urgent");
|
|
53
|
+
for (const item of urgent.slice(0, 3)) {
|
|
54
|
+
lines.push(formatEntry(item));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (needsReply.length > 0) {
|
|
58
|
+
lines.push("\n## Needs Reply");
|
|
59
|
+
for (const item of needsReply.slice(0, 5)) {
|
|
60
|
+
lines.push(formatEntry(item));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (recentAutoReplies.length > 0) {
|
|
64
|
+
lines.push("\n## Recent Auto-Replies");
|
|
65
|
+
for (const item of recentAutoReplies) {
|
|
66
|
+
const draftPreview = item.draftResponse ? `"${item.draftResponse.slice(0, 60)}..."` : "(no draft)";
|
|
67
|
+
lines.push(`- Sent to ${item.channelName}: ${draftPreview}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
lines.push("\nSay 'respond to [name/channel]' to draft and send replies.");
|
|
71
|
+
return {
|
|
72
|
+
text: lines.join("\n"),
|
|
73
|
+
values: {
|
|
74
|
+
inboxUnresolved: unresolved,
|
|
75
|
+
inboxUrgent: urgent.length,
|
|
76
|
+
inboxNeedsReply: needsReply.length
|
|
77
|
+
},
|
|
78
|
+
data: {
|
|
79
|
+
urgentItems: urgent,
|
|
80
|
+
needsReplyItems: needsReply,
|
|
81
|
+
recentAutoReplies
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
function formatEntry(entry) {
|
|
87
|
+
const senderInfo = entry.senderName ? ` from ${entry.senderName}` : "";
|
|
88
|
+
const link = entry.deepLink ? `
|
|
89
|
+
${entry.deepLink}` : "";
|
|
90
|
+
const snippet = entry.snippet.slice(0, 80);
|
|
91
|
+
return `- **${entry.channelName}**${senderInfo} (${entry.source}): "${snippet}"${link}`;
|
|
92
|
+
}
|
|
93
|
+
var inbox_triage_default = inboxTriageProvider;
|
|
94
|
+
export {
|
|
95
|
+
inbox_triage_default as default,
|
|
96
|
+
inboxTriageProvider
|
|
97
|
+
};
|
|
98
|
+
//# sourceMappingURL=inbox-triage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/providers/inbox-triage.ts"],"sourcesContent":["import { hasOwnerAccess } from \"@elizaos/agent/security/access\";\nimport type {\n IAgentRuntime,\n Memory,\n Provider,\n ProviderResult,\n State,\n} from \"@elizaos/core\";\nimport { logger } from \"@elizaos/core\";\nimport { InboxRepository } from \"../inbox/repository.js\";\nimport type { TriageEntry } from \"../inbox/types.js\";\n\nconst EMPTY: ProviderResult = {\n text: \"\",\n values: { inboxUnresolved: 0, inboxUrgent: 0 },\n data: {},\n};\n\n/**\n * inboxTriage provider — injects pending inbox triage items into owner context.\n *\n * Owner-only (`roleGate.minRole: OWNER` + the `hasOwnerAccess` gate below).\n * Because it only ever runs for the owner, the LifeOps egress redaction it used\n * is always a pass-through, so the ported provider surfaces the owner's full\n * triage snippets and deep links — observably identical to the LifeOps version.\n */\nexport const inboxTriageProvider: Provider = {\n name: \"inboxTriage\",\n description:\n \"Injects pending inbox triage items into owner context. Shows urgent messages, \" +\n \"items needing reply, and recent auto-replies across all channels including email. \" +\n \"Use MESSAGE action=triage/list_inbox/search_inbox/respond/draft_reply/send_draft for cross-channel triage, digest, respond, Gmail search/read, and Gmail draft/send reply workflows. \" +\n \"If the request is Gmail-only, MESSAGE should use source=gmail; if it is just 'my inbox', MESSAGE should use the cross-channel path.\",\n descriptionCompressed:\n \"Pending inbox triage items across all channels incl email.\",\n dynamic: true,\n position: 14, // after lifeops (12), before escalation (15)\n contexts: [\"email\", \"messaging\", \"tasks\"],\n contextGate: { anyOf: [\"email\", \"messaging\", \"tasks\"] },\n cacheScope: \"turn\",\n roleGate: { minRole: \"OWNER\" },\n\n async get(\n runtime: IAgentRuntime,\n message: Memory,\n _state: State,\n ): Promise<ProviderResult> {\n if (!(await hasOwnerAccess(runtime, message))) {\n return EMPTY;\n }\n\n let repo: InboxRepository;\n try {\n repo = new InboxRepository(runtime);\n } catch {\n return EMPTY;\n }\n\n let urgent: TriageEntry[];\n let needsReply: TriageEntry[];\n let recentAutoReplies: TriageEntry[];\n\n try {\n [urgent, needsReply, recentAutoReplies] = await Promise.all([\n repo.getByClassification(\"urgent\", { limit: 5 }),\n repo.getByClassification(\"needs_reply\", { limit: 10 }),\n repo.getRecentAutoReplies(5),\n ]);\n } catch (error) {\n logger.debug(\n \"[inbox-triage-provider] DB query failed (schema may not exist yet):\",\n String(error),\n );\n return EMPTY;\n }\n\n const unresolved = urgent.length + needsReply.length;\n if (unresolved === 0 && recentAutoReplies.length === 0) {\n return EMPTY;\n }\n\n const lines: string[] = [`# Inbox: ${unresolved} items pending`];\n\n if (urgent.length > 0) {\n lines.push(\"\\n## Urgent\");\n for (const item of urgent.slice(0, 3)) {\n lines.push(formatEntry(item));\n }\n }\n\n if (needsReply.length > 0) {\n lines.push(\"\\n## Needs Reply\");\n for (const item of needsReply.slice(0, 5)) {\n lines.push(formatEntry(item));\n }\n }\n\n if (recentAutoReplies.length > 0) {\n lines.push(\"\\n## Recent Auto-Replies\");\n for (const item of recentAutoReplies) {\n const draftPreview = item.draftResponse\n ? `\"${item.draftResponse.slice(0, 60)}...\"`\n : \"(no draft)\";\n lines.push(`- Sent to ${item.channelName}: ${draftPreview}`);\n }\n }\n\n lines.push(\"\\nSay 'respond to [name/channel]' to draft and send replies.\");\n\n return {\n text: lines.join(\"\\n\"),\n values: {\n inboxUnresolved: unresolved,\n inboxUrgent: urgent.length,\n inboxNeedsReply: needsReply.length,\n },\n data: {\n urgentItems: urgent,\n needsReplyItems: needsReply,\n recentAutoReplies,\n },\n };\n },\n};\n\nfunction formatEntry(entry: TriageEntry): string {\n const senderInfo = entry.senderName ? ` from ${entry.senderName}` : \"\";\n const link = entry.deepLink ? `\\n ${entry.deepLink}` : \"\";\n const snippet = entry.snippet.slice(0, 80);\n return `- **${entry.channelName}**${senderInfo} (${entry.source}): \"${snippet}\"${link}`;\n}\n\nexport default inboxTriageProvider;\n"],"mappings":"AAAA,SAAS,sBAAsB;AAQ/B,SAAS,cAAc;AACvB,SAAS,uBAAuB;AAGhC,MAAM,QAAwB;AAAA,EAC5B,MAAM;AAAA,EACN,QAAQ,EAAE,iBAAiB,GAAG,aAAa,EAAE;AAAA,EAC7C,MAAM,CAAC;AACT;AAUO,MAAM,sBAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,aACE;AAAA,EAIF,uBACE;AAAA,EACF,SAAS;AAAA,EACT,UAAU;AAAA;AAAA,EACV,UAAU,CAAC,SAAS,aAAa,OAAO;AAAA,EACxC,aAAa,EAAE,OAAO,CAAC,SAAS,aAAa,OAAO,EAAE;AAAA,EACtD,YAAY;AAAA,EACZ,UAAU,EAAE,SAAS,QAAQ;AAAA,EAE7B,MAAM,IACJ,SACA,SACA,QACyB;AACzB,QAAI,CAAE,MAAM,eAAe,SAAS,OAAO,GAAI;AAC7C,aAAO;AAAA,IACT;AAEA,QAAI;AACJ,QAAI;AACF,aAAO,IAAI,gBAAgB,OAAO;AAAA,IACpC,QAAQ;AACN,aAAO;AAAA,IACT;AAEA,QAAI;AACJ,QAAI;AACJ,QAAI;AAEJ,QAAI;AACF,OAAC,QAAQ,YAAY,iBAAiB,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC1D,KAAK,oBAAoB,UAAU,EAAE,OAAO,EAAE,CAAC;AAAA,QAC/C,KAAK,oBAAoB,eAAe,EAAE,OAAO,GAAG,CAAC;AAAA,QACrD,KAAK,qBAAqB,CAAC;AAAA,MAC7B,CAAC;AAAA,IACH,SAAS,OAAO;AACd,aAAO;AAAA,QACL;AAAA,QACA,OAAO,KAAK;AAAA,MACd;AACA,aAAO;AAAA,IACT;AAEA,UAAM,aAAa,OAAO,SAAS,WAAW;AAC9C,QAAI,eAAe,KAAK,kBAAkB,WAAW,GAAG;AACtD,aAAO;AAAA,IACT;AAEA,UAAM,QAAkB,CAAC,YAAY,UAAU,gBAAgB;AAE/D,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,KAAK,aAAa;AACxB,iBAAW,QAAQ,OAAO,MAAM,GAAG,CAAC,GAAG;AACrC,cAAM,KAAK,YAAY,IAAI,CAAC;AAAA,MAC9B;AAAA,IACF;AAEA,QAAI,WAAW,SAAS,GAAG;AACzB,YAAM,KAAK,kBAAkB;AAC7B,iBAAW,QAAQ,WAAW,MAAM,GAAG,CAAC,GAAG;AACzC,cAAM,KAAK,YAAY,IAAI,CAAC;AAAA,MAC9B;AAAA,IACF;AAEA,QAAI,kBAAkB,SAAS,GAAG;AAChC,YAAM,KAAK,0BAA0B;AACrC,iBAAW,QAAQ,mBAAmB;AACpC,cAAM,eAAe,KAAK,gBACtB,IAAI,KAAK,cAAc,MAAM,GAAG,EAAE,CAAC,SACnC;AACJ,cAAM,KAAK,aAAa,KAAK,WAAW,KAAK,YAAY,EAAE;AAAA,MAC7D;AAAA,IACF;AAEA,UAAM,KAAK,8DAA8D;AAEzE,WAAO;AAAA,MACL,MAAM,MAAM,KAAK,IAAI;AAAA,MACrB,QAAQ;AAAA,QACN,iBAAiB;AAAA,QACjB,aAAa,OAAO;AAAA,QACpB,iBAAiB,WAAW;AAAA,MAC9B;AAAA,MACA,MAAM;AAAA,QACJ,aAAa;AAAA,QACb,iBAAiB;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,YAAY,OAA4B;AAC/C,QAAM,aAAa,MAAM,aAAa,SAAS,MAAM,UAAU,KAAK;AACpE,QAAM,OAAO,MAAM,WAAW;AAAA,IAAO,MAAM,QAAQ,KAAK;AACxD,QAAM,UAAU,MAAM,QAAQ,MAAM,GAAG,EAAE;AACzC,SAAO,OAAO,MAAM,WAAW,KAAK,UAAU,KAAK,MAAM,MAAM,OAAO,OAAO,IAAI,IAAI;AACvF;AAEA,IAAO,uBAAQ;","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register the inbox view for terminal rendering.
|
|
3
|
+
*
|
|
4
|
+
* The agent terminal mounts plugin views by id from the `@elizaos/tui` terminal
|
|
5
|
+
* registry. This makes the inbox `tui` modality render for real in the terminal
|
|
6
|
+
* (the unified {@link InboxSpatialView}) rather than only navigating a GUI
|
|
7
|
+
* shell. A module-level snapshot lets a host push live inbox data; on a host
|
|
8
|
+
* with no inbox data it defaults to the loading snapshot.
|
|
9
|
+
*/
|
|
10
|
+
import { type InboxSnapshot } from "./components/inbox/InboxSpatialView.js";
|
|
11
|
+
/** Update the snapshot the registered terminal view renders from. */
|
|
12
|
+
export declare function setInboxTerminalSnapshot(next: InboxSnapshot): void;
|
|
13
|
+
/** Register the inbox terminal view; returns an unregister function. */
|
|
14
|
+
export declare function registerInboxTerminalView(): () => void;
|
|
15
|
+
//# sourceMappingURL=register-terminal-view.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-terminal-view.d.ts","sourceRoot":"","sources":["../src/register-terminal-view.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAEL,KAAK,aAAa,EAEnB,MAAM,yCAAyC,CAAC;AAIjD,qEAAqE;AACrE,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAElE;AAED,wEAAwE;AACxE,wBAAgB,yBAAyB,IAAI,MAAM,IAAI,CAItD"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { registerSpatialTerminalView } from "@elizaos/ui/spatial/tui";
|
|
2
|
+
import { createElement } from "react";
|
|
3
|
+
import {
|
|
4
|
+
EMPTY_INBOX_SNAPSHOT,
|
|
5
|
+
InboxSpatialView
|
|
6
|
+
} from "./components/inbox/InboxSpatialView.js";
|
|
7
|
+
let current = EMPTY_INBOX_SNAPSHOT;
|
|
8
|
+
function setInboxTerminalSnapshot(next) {
|
|
9
|
+
current = next;
|
|
10
|
+
}
|
|
11
|
+
function registerInboxTerminalView() {
|
|
12
|
+
return registerSpatialTerminalView(
|
|
13
|
+
"inbox",
|
|
14
|
+
() => createElement(InboxSpatialView, { snapshot: current })
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
registerInboxTerminalView,
|
|
19
|
+
setInboxTerminalSnapshot
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=register-terminal-view.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/register-terminal-view.tsx"],"sourcesContent":["/**\n * Register the inbox view for terminal rendering.\n *\n * The agent terminal mounts plugin views by id from the `@elizaos/tui` terminal\n * registry. This makes the inbox `tui` modality render for real in the terminal\n * (the unified {@link InboxSpatialView}) rather than only navigating a GUI\n * shell. A module-level snapshot lets a host push live inbox data; on a host\n * with no inbox data it defaults to the loading snapshot.\n */\n\nimport { registerSpatialTerminalView } from \"@elizaos/ui/spatial/tui\";\nimport { createElement } from \"react\";\nimport {\n EMPTY_INBOX_SNAPSHOT,\n type InboxSnapshot,\n InboxSpatialView,\n} from \"./components/inbox/InboxSpatialView.js\";\n\nlet current: InboxSnapshot = EMPTY_INBOX_SNAPSHOT;\n\n/** Update the snapshot the registered terminal view renders from. */\nexport function setInboxTerminalSnapshot(next: InboxSnapshot): void {\n current = next;\n}\n\n/** Register the inbox terminal view; returns an unregister function. */\nexport function registerInboxTerminalView(): () => void {\n return registerSpatialTerminalView(\"inbox\", () =>\n createElement(InboxSpatialView, { snapshot: current }),\n );\n}\n"],"mappings":"AAUA,SAAS,mCAAmC;AAC5C,SAAS,qBAAqB;AAC9B;AAAA,EACE;AAAA,EAEA;AAAA,OACK;AAEP,IAAI,UAAyB;AAGtB,SAAS,yBAAyB,MAA2B;AAClE,YAAU;AACZ;AAGO,SAAS,4BAAwC;AACtD,SAAO;AAAA,IAA4B;AAAA,IAAS,MAC1C,cAAc,kBAAkB,EAAE,UAAU,QAAQ,CAAC;AAAA,EACvD;AACF;","names":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Side-effect entry point — registers the inbox view for terminal rendering.
|
|
3
|
+
*
|
|
4
|
+
* In a terminal host (the Node agent, no DOM), register the inbox view so it
|
|
5
|
+
* renders inline in the terminal. Lazy + DOM-guarded so the terminal engine
|
|
6
|
+
* stays out of browser/mobile bundles. Web, iOS, desktop, and Android leave the
|
|
7
|
+
* import inert, so the same import is safe everywhere.
|
|
8
|
+
*/
|
|
9
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
package/dist/register.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/register.ts"],"sourcesContent":["/**\n * Side-effect entry point — registers the inbox view for terminal rendering.\n *\n * In a terminal host (the Node agent, no DOM), register the inbox view so it\n * renders inline in the terminal. Lazy + DOM-guarded so the terminal engine\n * stays out of browser/mobile bundles. Web, iOS, desktop, and Android leave the\n * import inert, so the same import is safe everywhere.\n */\n\nif (typeof window === \"undefined\") {\n void import(\"./register-terminal-view.js\")\n .then((m) => m.registerInboxTerminalView())\n .catch(() => {\n // Terminal rendering is best-effort; never block plugin load.\n });\n}\n"],"mappings":"AASA,IAAI,OAAO,WAAW,aAAa;AACjC,OAAK,OAAO,6BAA6B,EACtC,KAAK,CAAC,MAAM,EAAE,0BAA0B,CAAC,EACzC,MAAM,MAAM;AAAA,EAEb,CAAC;AACL;","names":[]}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* View-facing type surface for @elizaos/plugin-inbox.
|
|
3
|
+
*
|
|
4
|
+
* These are the display contract the `InboxView` renders against. The triage
|
|
5
|
+
* back-end types (TriageEntry, TriageClassification, InboundMessage, …) live in
|
|
6
|
+
* `./inbox/types.ts`; the INBOX action's fan-out types live in
|
|
7
|
+
* `./actions/inbox.ts`. This plugin must not import from
|
|
8
|
+
* @elizaos/plugin-personal-assistant.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Channels the unified inbox aggregates. These mirror the wire channel ids the
|
|
12
|
+
* inbox route emits (`LIFEOPS_INBOX_CHANNELS` in @elizaos/shared) so the view
|
|
13
|
+
* can group the real payload without a translation table. Defined locally —
|
|
14
|
+
* this plugin must not import from @elizaos/plugin-personal-assistant.
|
|
15
|
+
*/
|
|
16
|
+
export declare const INBOX_CHANNELS: readonly ["gmail", "x_dm", "discord", "telegram", "signal", "imessage", "whatsapp", "sms"];
|
|
17
|
+
export type InboxChannel = (typeof INBOX_CHANNELS)[number];
|
|
18
|
+
/** Human-readable label per channel, in display order. */
|
|
19
|
+
export declare const INBOX_CHANNEL_LABELS: Record<InboxChannel, string>;
|
|
20
|
+
/**
|
|
21
|
+
* One triage item rendered by the InboxView. This is the view's local display
|
|
22
|
+
* DTO, mapped at the fetch boundary from a `LifeOpsInboxMessage` on the wire
|
|
23
|
+
* (`GET /api/lifeops/inbox`). It is intentionally a flat, display-only shape —
|
|
24
|
+
* the view reads these fields and formats them, it never computes.
|
|
25
|
+
*/
|
|
26
|
+
export interface InboxItem {
|
|
27
|
+
/** Channel-prefixed, globally unique message id. */
|
|
28
|
+
id: string;
|
|
29
|
+
channel: InboxChannel;
|
|
30
|
+
/** Display name of the sender. */
|
|
31
|
+
sender: string;
|
|
32
|
+
/** Gmail-style subject; null for chat channels. */
|
|
33
|
+
subject: string | null;
|
|
34
|
+
/** One-line preview of the latest message. */
|
|
35
|
+
preview: string;
|
|
36
|
+
/** ISO-8601 timestamp the message was received. */
|
|
37
|
+
receivedAt: string;
|
|
38
|
+
unread: boolean;
|
|
39
|
+
/** Stable per-conversation key, when the wire supplies one. */
|
|
40
|
+
threadId: string | null;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,cAAc,4FASjB,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE3D,0DAA0D;AAC1D,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAS7D,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,oDAAoD;IACpD,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,YAAY,CAAC;IACtB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const INBOX_CHANNELS = [
|
|
2
|
+
"gmail",
|
|
3
|
+
"x_dm",
|
|
4
|
+
"discord",
|
|
5
|
+
"telegram",
|
|
6
|
+
"signal",
|
|
7
|
+
"imessage",
|
|
8
|
+
"whatsapp",
|
|
9
|
+
"sms"
|
|
10
|
+
];
|
|
11
|
+
const INBOX_CHANNEL_LABELS = {
|
|
12
|
+
gmail: "Email",
|
|
13
|
+
x_dm: "X",
|
|
14
|
+
discord: "Discord",
|
|
15
|
+
telegram: "Telegram",
|
|
16
|
+
signal: "Signal",
|
|
17
|
+
imessage: "iMessage",
|
|
18
|
+
whatsapp: "WhatsApp",
|
|
19
|
+
sms: "SMS"
|
|
20
|
+
};
|
|
21
|
+
export {
|
|
22
|
+
INBOX_CHANNELS,
|
|
23
|
+
INBOX_CHANNEL_LABELS
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * View-facing type surface for @elizaos/plugin-inbox.\n *\n * These are the display contract the `InboxView` renders against. The triage\n * back-end types (TriageEntry, TriageClassification, InboundMessage, …) live in\n * `./inbox/types.ts`; the INBOX action's fan-out types live in\n * `./actions/inbox.ts`. This plugin must not import from\n * @elizaos/plugin-personal-assistant.\n */\n\n/**\n * Channels the unified inbox aggregates. These mirror the wire channel ids the\n * inbox route emits (`LIFEOPS_INBOX_CHANNELS` in @elizaos/shared) so the view\n * can group the real payload without a translation table. Defined locally —\n * this plugin must not import from @elizaos/plugin-personal-assistant.\n */\nexport const INBOX_CHANNELS = [\n \"gmail\",\n \"x_dm\",\n \"discord\",\n \"telegram\",\n \"signal\",\n \"imessage\",\n \"whatsapp\",\n \"sms\",\n] as const;\nexport type InboxChannel = (typeof INBOX_CHANNELS)[number];\n\n/** Human-readable label per channel, in display order. */\nexport const INBOX_CHANNEL_LABELS: Record<InboxChannel, string> = {\n gmail: \"Email\",\n x_dm: \"X\",\n discord: \"Discord\",\n telegram: \"Telegram\",\n signal: \"Signal\",\n imessage: \"iMessage\",\n whatsapp: \"WhatsApp\",\n sms: \"SMS\",\n};\n\n/**\n * One triage item rendered by the InboxView. This is the view's local display\n * DTO, mapped at the fetch boundary from a `LifeOpsInboxMessage` on the wire\n * (`GET /api/lifeops/inbox`). It is intentionally a flat, display-only shape —\n * the view reads these fields and formats them, it never computes.\n */\nexport interface InboxItem {\n /** Channel-prefixed, globally unique message id. */\n id: string;\n channel: InboxChannel;\n /** Display name of the sender. */\n sender: string;\n /** Gmail-style subject; null for chat channels. */\n subject: string | null;\n /** One-line preview of the latest message. */\n preview: string;\n /** ISO-8601 timestamp the message was received. */\n receivedAt: string;\n unread: boolean;\n /** Stable per-conversation key, when the wire supplies one. */\n threadId: string | null;\n}\n"],"mappings":"AAgBO,MAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,uBAAqD;AAAA,EAChE,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,UAAU;AAAA,EACV,KAAK;AACP;","names":[]}
|