@agenticmail/api 0.9.15 → 0.9.16
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/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Claude</title><path d="M4.709 15.955l4.72-2.647.08-.23-.08-.128H9.2l-.79-.048-2.698-.073-2.339-.097-2.266-.122-.571-.121L0 11.784l.055-.352.48-.321.686.06 1.52.103 2.278.158 1.652.097 2.449.255h.389l.055-.157-.134-.098-.103-.097-2.358-1.596-2.552-1.688-1.336-.972-.724-.491-.364-.462-.158-1.008.656-.722.881.06.225.061.893.686 1.908 1.476 2.491 1.833.365.304.145-.103.019-.073-.164-.274-1.355-2.446-1.446-2.49-.644-1.032-.17-.619a2.97 2.97 0 01-.104-.729L6.283.134 6.696 0l.996.134.42.364.62 1.414 1.002 2.229 1.555 3.03.456.898.243.832.091.255h.158V9.01l.128-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.584.28.48.685-.067.444-.286 1.851-.559 2.903-.364 1.942h.212l.243-.242.985-1.306 1.652-2.064.73-.82.85-.904.547-.431h1.033l.76 1.129-.34 1.166-1.064 1.347-.881 1.142-1.264 1.7-.79 1.36.073.11.188-.02 2.856-.606 1.543-.28 1.841-.315.833.388.091.395-.328.807-1.969.486-2.309.462-3.439.813-.042.03.049.061 1.549.146.662.036h1.622l3.02.225.79.522.474.638-.079.485-1.215.62-1.64-.389-3.829-.91-1.312-.329h-.182v.11l1.093 1.068 2.006 1.81 2.509 2.33.127.578-.322.455-.34-.049-2.205-1.657-.851-.747-1.926-1.62h-.128v.17l.444.649 2.345 3.521.122 1.08-.17.353-.608.213-.668-.122-1.374-1.925-1.415-2.167-1.143-1.943-.14.08-.674 7.254-.316.37-.729.28-.607-.461-.322-.747.322-1.476.389-1.924.315-1.53.286-1.9.17-.632-.012-.042-.14.018-1.434 1.967-2.18 2.945-1.726 1.845-.414.164-.717-.37.067-.662.401-.589 2.388-3.036 1.44-1.882.93-1.086-.006-.158h-.055L4.132 18.56l-1.13.146-.487-.456.061-.746.231-.243 1.908-1.312-.006.006z" fill="#D97757" fill-rule="nonzero"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>OpenAI</title><path d="M9.205 8.658v-2.26c0-.19.072-.333.238-.428l4.543-2.616c.619-.357 1.356-.523 2.117-.523 2.854 0 4.662 2.212 4.662 4.566 0 .167 0 .357-.024.547l-4.71-2.759a.797.797 0 00-.856 0l-5.97 3.473zm10.609 8.8V12.06c0-.333-.143-.57-.429-.737l-5.97-3.473 1.95-1.118a.433.433 0 01.476 0l4.543 2.617c1.309.76 2.189 2.378 2.189 3.948 0 1.808-1.07 3.473-2.76 4.163zM7.802 12.703l-1.95-1.142c-.167-.095-.239-.238-.239-.428V5.899c0-2.545 1.95-4.472 4.591-4.472 1 0 1.927.333 2.712.928L8.23 5.067c-.285.166-.428.404-.428.737v6.898zM12 15.128l-2.795-1.57v-3.33L12 8.658l2.795 1.57v3.33L12 15.128zm1.796 7.23c-1 0-1.927-.332-2.712-.927l4.686-2.712c.285-.166.428-.404.428-.737v-6.898l1.974 1.142c.167.095.238.238.238.428v5.233c0 2.545-1.974 4.472-4.614 4.472zm-5.637-5.303l-4.544-2.617c-1.308-.761-2.188-2.378-2.188-3.948A4.482 4.482 0 014.21 6.327v5.423c0 .333.143.571.428.738l5.947 3.449-1.95 1.118a.432.432 0 01-.476 0zm-.262 3.9c-2.688 0-4.662-2.021-4.662-4.519 0-.19.024-.38.047-.57l4.686 2.71c.286.167.571.167.856 0l5.97-3.448v2.26c0 .19-.07.333-.237.428l-4.543 2.616c-.619.357-1.356.523-2.117.523zm5.899 2.83a5.947 5.947 0 005.827-4.756C22.287 18.339 24 15.84 24 13.296c0-1.665-.713-3.282-1.998-4.448.119-.5.19-.999.19-1.498 0-3.401-2.759-5.947-5.946-5.947-.642 0-1.26.095-1.88.31A5.962 5.962 0 0010.205 0a5.947 5.947 0 00-5.827 4.757C1.713 5.447 0 7.945 0 10.49c0 1.666.713 3.283 1.998 4.448-.119.5-.19 1-.19 1.499 0 3.401 2.759 5.946 5.946 5.946.642 0 1.26-.095 1.88-.309a5.96 5.96 0 004.162 1.713z"></path></svg>
|
package/public/js/avatar.js
CHANGED
|
@@ -1,23 +1,84 @@
|
|
|
1
1
|
// Agent identity + avatar helpers.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// the
|
|
3
|
+
// Each host integration (Claude Code, Codex, …) gets its own branded
|
|
4
|
+
// avatar in the web UI so multiple co-installed bridges can be told
|
|
5
|
+
// apart at a glance. The HOST_BRANDING table below registers one entry
|
|
6
|
+
// per known host integration. Adding a new host = add one row + drop
|
|
7
|
+
// the SVG into /branding/.
|
|
8
8
|
import { escapeHtml } from './utils.js';
|
|
9
9
|
import { icon } from './icons.js';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Registry of host integrations → branding.
|
|
13
|
+
*
|
|
14
|
+
* key metadata.host value (lowercased)
|
|
15
|
+
* logoUrl path under /branding/, served as a static asset
|
|
16
|
+
* altText alt= text on the <img>
|
|
17
|
+
* aliases legacy / alternate names that should map to this host
|
|
18
|
+
* (some bridges historically used the host's product
|
|
19
|
+
* name instead of the host id)
|
|
20
|
+
*
|
|
21
|
+
* The lookup picks an entry by, in order:
|
|
22
|
+
* 1. agent.metadata.host
|
|
23
|
+
* 2. agent.name (so a bridge with name 'codex' but no metadata.host
|
|
24
|
+
* still renders correctly during the upgrade window)
|
|
25
|
+
* 3. any alias listed under a host
|
|
26
|
+
*/
|
|
27
|
+
const HOST_BRANDING = {
|
|
28
|
+
claudecode: {
|
|
29
|
+
logoUrl: '/branding/claude-color.svg',
|
|
30
|
+
altText: 'Claude',
|
|
31
|
+
aliases: ['claude'],
|
|
32
|
+
},
|
|
33
|
+
codex: {
|
|
34
|
+
logoUrl: '/branding/openai-mark.svg',
|
|
35
|
+
altText: 'OpenAI Codex',
|
|
36
|
+
aliases: ['openai', 'chatgpt'],
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// Fallback when we know an account is a bridge but can't identify which
|
|
41
|
+
// host owns it (legacy account with no host tag, unknown host name).
|
|
42
|
+
// Better than mis-attributing — a generic host badge plus a verified
|
|
43
|
+
// tick still reads as "this is a host, not a teammate".
|
|
44
|
+
const GENERIC_HOST_LOGO = '/branding/agenticmail-logo.png';
|
|
15
45
|
|
|
16
46
|
export function isBridgeAgent(agent) {
|
|
17
47
|
if (!agent) return false;
|
|
18
48
|
const name = (agent.name ?? '').toLowerCase();
|
|
19
49
|
const role = (agent.role ?? '').toLowerCase();
|
|
20
|
-
|
|
50
|
+
const meta = agent.metadata ?? {};
|
|
51
|
+
if (role === 'bridge') return true;
|
|
52
|
+
if (meta && meta.bridge === true) return true;
|
|
53
|
+
// Name-based fallback for pre-0.9.3 bridges that still use role='assistant'.
|
|
54
|
+
if (HOST_BRANDING[name]) return true;
|
|
55
|
+
for (const entry of Object.values(HOST_BRANDING)) {
|
|
56
|
+
if (entry.aliases?.includes(name)) return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Resolve the host branding entry for an agent. Returns null when the
|
|
63
|
+
* agent isn't a bridge or can't be matched to a known host.
|
|
64
|
+
*/
|
|
65
|
+
function brandingFor(agent) {
|
|
66
|
+
if (!agent) return null;
|
|
67
|
+
const name = (agent.name ?? '').toLowerCase();
|
|
68
|
+
const metaHost = (agent.metadata?.host ?? '').toString().toLowerCase();
|
|
69
|
+
|
|
70
|
+
// 1. Trust the host tag first — it's the canonical source of truth.
|
|
71
|
+
if (metaHost && HOST_BRANDING[metaHost]) return HOST_BRANDING[metaHost];
|
|
72
|
+
|
|
73
|
+
// 2. Fall back to matching the bridge name itself.
|
|
74
|
+
if (HOST_BRANDING[name]) return HOST_BRANDING[name];
|
|
75
|
+
|
|
76
|
+
// 3. Check aliases (e.g. a bridge literally named 'claude').
|
|
77
|
+
for (const entry of Object.values(HOST_BRANDING)) {
|
|
78
|
+
if (entry.aliases?.includes(name)) return entry;
|
|
79
|
+
if (entry.aliases?.includes(metaHost)) return entry;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
21
82
|
}
|
|
22
83
|
|
|
23
84
|
// Deterministic colour per agent name — keeps teammate colours stable
|
|
@@ -35,7 +96,10 @@ function avatarColorFor(name) {
|
|
|
35
96
|
export function avatarHtml(agent, size = '') {
|
|
36
97
|
const cls = `avatar ${size}`.trim();
|
|
37
98
|
if (isBridgeAgent(agent)) {
|
|
38
|
-
|
|
99
|
+
const brand = brandingFor(agent);
|
|
100
|
+
const url = brand?.logoUrl ?? GENERIC_HOST_LOGO;
|
|
101
|
+
const alt = brand?.altText ?? 'Host';
|
|
102
|
+
return `<span class="${cls} avatar-host"><img src="${url}" alt="${escapeHtml(alt)}" class="avatar-img" /><span class="avatar-check">${icon('check', { size: 10 })}</span></span>`;
|
|
39
103
|
}
|
|
40
104
|
const initial = (agent.name ?? '?').slice(0, 1).toUpperCase();
|
|
41
105
|
const color = avatarColorFor(agent.name ?? '');
|