More fixes
This commit is contained in:
parent
0d73dea914
commit
a1182ccd04
@ -13,8 +13,7 @@
|
|||||||
"selectionLabel": "AgentMail (Email Inbox API)",
|
"selectionLabel": "AgentMail (Email Inbox API)",
|
||||||
"docsPath": "/channels/agentmail",
|
"docsPath": "/channels/agentmail",
|
||||||
"docsLabel": "agentmail",
|
"docsLabel": "agentmail",
|
||||||
"blurb": "Email channel via AgentMail; configure API key and inbox.",
|
"blurb": "email channel via AgentMail; dedicated agent inbox API.",
|
||||||
"order": 0,
|
|
||||||
"quickstartAllowFrom": true
|
"quickstartAllowFrom": true
|
||||||
},
|
},
|
||||||
"install": {
|
"install": {
|
||||||
|
|||||||
@ -16,11 +16,10 @@ export function listAgentMailAccountIds(_cfg: CoreConfig): string[] {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the default AgentMail account ID.
|
* Returns the default AgentMail account ID.
|
||||||
|
* Currently only supports a single default account.
|
||||||
*/
|
*/
|
||||||
export function resolveDefaultAgentMailAccountId(cfg: CoreConfig): string {
|
export function resolveDefaultAgentMailAccountId(_cfg: CoreConfig): string {
|
||||||
const ids = listAgentMailAccountIds(cfg);
|
return DEFAULT_ACCOUNT_ID;
|
||||||
if (ids.includes(DEFAULT_ACCOUNT_ID)) return DEFAULT_ACCOUNT_ID;
|
|
||||||
return ids[0] ?? DEFAULT_ACCOUNT_ID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Resolved AgentMail credentials and paths. */
|
/** Resolved AgentMail credentials and paths. */
|
||||||
|
|||||||
@ -23,12 +23,13 @@ import type { CoreConfig, ResolvedAgentMailAccount } from "./utils.js";
|
|||||||
|
|
||||||
const meta = {
|
const meta = {
|
||||||
id: "agentmail",
|
id: "agentmail",
|
||||||
label: "AgentMail (Email Inbox API)",
|
label: "AgentMail",
|
||||||
selectionLabel: "AgentMail (Email Inbox API)",
|
selectionLabel: "AgentMail (Email Inbox API)",
|
||||||
|
detailLabel: "AgentMail",
|
||||||
docsPath: "/channels/agentmail",
|
docsPath: "/channels/agentmail",
|
||||||
docsLabel: "agentmail",
|
docsLabel: "agentmail",
|
||||||
blurb: "Email channel via AgentMail; configure token and email address.",
|
blurb: "email channel via AgentMail; dedicated agent inbox API.",
|
||||||
order: 80,
|
systemImage: "envelope",
|
||||||
quickstartAllowFrom: true,
|
quickstartAllowFrom: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -5,15 +5,21 @@ import { getAgentMailRuntime } from "./runtime.js";
|
|||||||
import type { CoreConfig } from "./utils.js";
|
import type { CoreConfig } from "./utils.js";
|
||||||
|
|
||||||
let sharedClient: AgentMailClient | null = null;
|
let sharedClient: AgentMailClient | null = null;
|
||||||
|
let sharedClientKey: string | null = null;
|
||||||
|
|
||||||
/** Creates or returns a shared AgentMailClient instance. */
|
/** Creates or returns a shared AgentMailClient instance. Recreates if key changed. */
|
||||||
export function getAgentMailClient(apiKey?: string): AgentMailClient {
|
export function getAgentMailClient(apiKey?: string): AgentMailClient {
|
||||||
if (sharedClient) return sharedClient;
|
|
||||||
|
|
||||||
const key = apiKey ?? getResolvedCredentials().apiKey;
|
const key = apiKey ?? getResolvedCredentials().apiKey;
|
||||||
if (!key) throw new Error("AgentMail token is required");
|
if (!key) throw new Error("AgentMail token is required");
|
||||||
|
|
||||||
|
// Return cached client if key matches
|
||||||
|
if (sharedClient && sharedClientKey === key) {
|
||||||
|
return sharedClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new client (key changed or first call)
|
||||||
sharedClient = new AgentMailClient({ apiKey: key });
|
sharedClient = new AgentMailClient({ apiKey: key });
|
||||||
|
sharedClientKey = key;
|
||||||
return sharedClient;
|
return sharedClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,11 +14,8 @@ export function matchesList(senderEmail: string, list: string[]): boolean {
|
|||||||
|
|
||||||
return list.some((entry) => {
|
return list.some((entry) => {
|
||||||
const normalizedEntry = entry.toLowerCase().trim();
|
const normalizedEntry = entry.toLowerCase().trim();
|
||||||
return (
|
// Match exact email or domain
|
||||||
normalizedEntry === normalizedSender || // exact email match
|
return normalizedEntry === normalizedSender || normalizedEntry === domain;
|
||||||
normalizedEntry === domain || // exact domain match
|
|
||||||
normalizedSender.endsWith(`@${normalizedEntry}`) // domain suffix match
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,7 @@ function recordState(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns runtime state for status checks. */
|
||||||
export function getAgentMailRuntimeState(accountId: string) {
|
export function getAgentMailRuntimeState(accountId: string) {
|
||||||
return runtimeState.get(`agentmail:${accountId}`);
|
return runtimeState.get(`agentmail:${accountId}`);
|
||||||
}
|
}
|
||||||
@ -158,8 +159,12 @@ export async function monitorAgentMailProvider(
|
|||||||
return sendJson(res, 200, { ok: true, filtered: true });
|
return sendJson(res, 200, { ok: true, filtered: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Label message as allowed
|
// Label message as allowed (best effort - don't fail if labeling fails)
|
||||||
await labelMessageAllowed(client, inboxId, message.messageId);
|
try {
|
||||||
|
await labelMessageAllowed(client, inboxId, message.messageId);
|
||||||
|
} catch (labelErr) {
|
||||||
|
logVerbose(`agentmail: failed to label message: ${String(labelErr)}`);
|
||||||
|
}
|
||||||
|
|
||||||
recordState(accountId, { lastInboundAt: Date.now() });
|
recordState(accountId, { lastInboundAt: Date.now() });
|
||||||
|
|
||||||
|
|||||||
@ -94,8 +94,8 @@ export async function fetchFormattedThread(
|
|||||||
const messages = thread.messages.map(formatMessage).join("\n\n");
|
const messages = thread.messages.map(formatMessage).join("\n\n");
|
||||||
|
|
||||||
return `${header}\n\n${messages}`;
|
return `${header}\n\n${messages}`;
|
||||||
} catch (err) {
|
} catch {
|
||||||
console.error(`Failed to fetch thread: ${String(err)}`);
|
// Caller handles fallback to webhook payload
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -213,6 +213,30 @@ const DOCKS: Record<ChatChannelId, ChannelDock> = {
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
agentmail: {
|
||||||
|
id: "agentmail",
|
||||||
|
capabilities: {
|
||||||
|
chatTypes: ["direct"],
|
||||||
|
media: true,
|
||||||
|
threads: true,
|
||||||
|
},
|
||||||
|
outbound: { textChunkLimit: 4000 },
|
||||||
|
config: {
|
||||||
|
resolveAllowFrom: ({ cfg }) =>
|
||||||
|
((cfg.channels?.agentmail as { allowFrom?: string[] } | undefined)?.allowFrom ?? []).map(
|
||||||
|
(entry) => String(entry),
|
||||||
|
),
|
||||||
|
formatAllowFrom: ({ allowFrom }) => formatLower(allowFrom),
|
||||||
|
},
|
||||||
|
threading: {
|
||||||
|
buildToolContext: ({ context, hasRepliedRef }) => ({
|
||||||
|
currentChannelId: context.To?.trim() || undefined,
|
||||||
|
currentThreadTs:
|
||||||
|
context.MessageThreadId != null ? String(context.MessageThreadId) : undefined,
|
||||||
|
hasRepliedRef,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
googlechat: {
|
googlechat: {
|
||||||
id: "googlechat",
|
id: "googlechat",
|
||||||
capabilities: {
|
capabilities: {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user