@agenticmail/enterprise 0.5.199 → 0.5.200

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/dashboard/pages/activity.js +14 -1
  2. package/dist/dashboard/pages/agent-detail/activity.js +17 -1
  3. package/dist/dashboard/pages/agent-detail/autonomy.js +17 -1
  4. package/dist/dashboard/pages/agent-detail/budget.js +25 -2
  5. package/dist/dashboard/pages/agent-detail/channels.js +10 -1
  6. package/dist/dashboard/pages/agent-detail/communication.js +10 -1
  7. package/dist/dashboard/pages/agent-detail/configuration.js +42 -1
  8. package/dist/dashboard/pages/agent-detail/deployment.js +147 -16
  9. package/dist/dashboard/pages/agent-detail/email.js +10 -1
  10. package/dist/dashboard/pages/agent-detail/guardrails.js +27 -3
  11. package/dist/dashboard/pages/agent-detail/manager.js +15 -1
  12. package/dist/dashboard/pages/agent-detail/meeting-browser.js +14 -2
  13. package/dist/dashboard/pages/agent-detail/memory.js +24 -5
  14. package/dist/dashboard/pages/agent-detail/overview.js +159 -21
  15. package/dist/dashboard/pages/agent-detail/permissions.js +28 -7
  16. package/dist/dashboard/pages/agent-detail/personal-details.js +17 -1
  17. package/dist/dashboard/pages/agent-detail/security.js +21 -5
  18. package/dist/dashboard/pages/agent-detail/skills-section.js +9 -1
  19. package/dist/dashboard/pages/agent-detail/tool-security.js +35 -8
  20. package/dist/dashboard/pages/agent-detail/tools.js +10 -1
  21. package/dist/dashboard/pages/agent-detail/whatsapp.js +11 -1
  22. package/dist/dashboard/pages/agent-detail/workforce.js +19 -4
  23. package/dist/dashboard/pages/agents.js +15 -1
  24. package/dist/dashboard/pages/approvals.js +15 -1
  25. package/dist/dashboard/pages/audit.js +23 -1
  26. package/dist/dashboard/pages/compliance.js +24 -2
  27. package/dist/dashboard/pages/dashboard.js +25 -6
  28. package/dist/dashboard/pages/dlp.js +23 -2
  29. package/dist/dashboard/pages/domain-status.js +51 -7
  30. package/dist/dashboard/pages/guardrails.js +29 -3
  31. package/dist/dashboard/pages/journal.js +24 -4
  32. package/dist/dashboard/pages/knowledge-contributions.js +69 -3
  33. package/dist/dashboard/pages/knowledge-import.js +6 -1
  34. package/dist/dashboard/pages/knowledge.js +51 -9
  35. package/dist/dashboard/pages/messages.js +28 -5
  36. package/dist/dashboard/pages/org-chart.js +18 -1
  37. package/dist/dashboard/pages/settings.js +30 -6
  38. package/dist/dashboard/pages/skill-connections.js +18 -4
  39. package/dist/dashboard/pages/skills.js +11 -1
  40. package/dist/dashboard/pages/users.js +14 -1
  41. package/dist/dashboard/pages/vault.js +22 -2
  42. package/dist/dashboard/pages/workforce.js +17 -1
  43. package/package.json +1 -1
  44. package/src/dashboard/HELP-TOOLTIPS-GUIDE.md +45 -0
  45. package/src/dashboard/pages/activity.js +14 -1
  46. package/src/dashboard/pages/agent-detail/activity.js +17 -1
  47. package/src/dashboard/pages/agent-detail/autonomy.js +17 -1
  48. package/src/dashboard/pages/agent-detail/budget.js +25 -2
  49. package/src/dashboard/pages/agent-detail/channels.js +10 -1
  50. package/src/dashboard/pages/agent-detail/communication.js +10 -1
  51. package/src/dashboard/pages/agent-detail/configuration.js +42 -1
  52. package/src/dashboard/pages/agent-detail/deployment.js +147 -16
  53. package/src/dashboard/pages/agent-detail/email.js +10 -1
  54. package/src/dashboard/pages/agent-detail/guardrails.js +27 -3
  55. package/src/dashboard/pages/agent-detail/manager.js +15 -1
  56. package/src/dashboard/pages/agent-detail/meeting-browser.js +14 -2
  57. package/src/dashboard/pages/agent-detail/memory.js +24 -5
  58. package/src/dashboard/pages/agent-detail/overview.js +159 -21
  59. package/src/dashboard/pages/agent-detail/permissions.js +28 -7
  60. package/src/dashboard/pages/agent-detail/personal-details.js +17 -1
  61. package/src/dashboard/pages/agent-detail/security.js +21 -5
  62. package/src/dashboard/pages/agent-detail/skills-section.js +9 -1
  63. package/src/dashboard/pages/agent-detail/tool-security.js +35 -8
  64. package/src/dashboard/pages/agent-detail/tools.js +10 -1
  65. package/src/dashboard/pages/agent-detail/whatsapp.js +11 -1
  66. package/src/dashboard/pages/agent-detail/workforce.js +19 -4
  67. package/src/dashboard/pages/agents.js +15 -1
  68. package/src/dashboard/pages/approvals.js +15 -1
  69. package/src/dashboard/pages/audit.js +23 -1
  70. package/src/dashboard/pages/compliance.js +24 -2
  71. package/src/dashboard/pages/dashboard.js +25 -6
  72. package/src/dashboard/pages/dlp.js +23 -2
  73. package/src/dashboard/pages/domain-status.js +51 -7
  74. package/src/dashboard/pages/guardrails.js +29 -3
  75. package/src/dashboard/pages/journal.js +24 -4
  76. package/src/dashboard/pages/knowledge-contributions.js +69 -3
  77. package/src/dashboard/pages/knowledge-import.js +6 -1
  78. package/src/dashboard/pages/knowledge.js +51 -9
  79. package/src/dashboard/pages/messages.js +28 -5
  80. package/src/dashboard/pages/org-chart.js +18 -1
  81. package/src/dashboard/pages/settings.js +30 -6
  82. package/src/dashboard/pages/skill-connections.js +18 -4
  83. package/src/dashboard/pages/skills.js +11 -1
  84. package/src/dashboard/pages/users.js +14 -1
  85. package/src/dashboard/pages/vault.js +22 -2
  86. package/src/dashboard/pages/workforce.js +17 -1
@@ -1,6 +1,7 @@
1
1
  import { h, useState, useEffect, useCallback, Fragment, useApp, apiCall, showConfirm } from '../components/utils.js';
2
2
  import { I } from '../components/icons.js';
3
3
  import { E } from '../assets/icons/emoji-icons.js';
4
+ import { HelpButton } from '../components/help-button.js';
4
5
 
5
6
  export function DomainStatusPage() {
6
7
  var { toast } = useApp();
@@ -165,6 +166,9 @@ export function DomainStatusPage() {
165
166
  var sub = data && data.subdomain;
166
167
 
167
168
  // ─── Styles ──────────────────────────────────
169
+ var _h4 = { marginTop: 16, marginBottom: 8, fontSize: 14 };
170
+ var _ul = { paddingLeft: 20, margin: '4px 0 8px' };
171
+ var _tip = { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 };
168
172
  var card = { padding: 24, background: 'var(--bg-secondary)', borderRadius: 'var(--radius-lg)', border: '1px solid var(--border)', marginBottom: 16 };
169
173
  var labelSt = { fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 0.8, marginBottom: 10 };
170
174
  var rowSt = { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '10px 0', borderBottom: '1px solid var(--border)' };
@@ -172,7 +176,18 @@ export function DomainStatusPage() {
172
176
  return h(Fragment, null,
173
177
  // ─── Page Header ──────────────────────────────
174
178
  h('div', { style: { marginBottom: 24 } },
175
- h('h1', { style: { fontSize: 20, fontWeight: 700 } }, 'Domain & Deployment'),
179
+ h('h1', { style: { fontSize: 20, fontWeight: 700, display: 'flex', alignItems: 'center' } }, 'Domain & Deployment', h(HelpButton, { label: 'Domain & Deployment' },
180
+ h('p', null, 'Configure how your AgenticMail Enterprise instance is accessed on the internet. Set up subdomains, custom domains, CORS policies, and deployment tunnels.'),
181
+ h('h4', { style: _h4 }, 'Sections'),
182
+ h('ul', { style: _ul },
183
+ h('li', null, h('strong', null, 'Current Deployment'), ' — The URL where your dashboard is running right now.'),
184
+ h('li', null, h('strong', null, 'Subdomain'), ' — Your free agenticmail.io subdomain.'),
185
+ h('li', null, h('strong', null, 'Custom Domain'), ' — Use your own domain with DNS verification.'),
186
+ h('li', null, h('strong', null, 'CORS'), ' — Control which origins can make API requests.'),
187
+ h('li', null, h('strong', null, 'Migration'), ' — Move your deployment to another machine.')
188
+ ),
189
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'If running locally, use the "Deploy to Production" section to expose your instance via a Cloudflare Tunnel.')
190
+ )),
176
191
  h('p', { style: { color: 'var(--text-muted)', fontSize: 13 } }, 'Manage the domain and URL for your AgenticMail Enterprise deployment')
177
192
  ),
178
193
 
@@ -185,7 +200,10 @@ export function DomainStatusPage() {
185
200
  // SECTION 1: Current Deployment
186
201
  // ═══════════════════════════════════════════════
187
202
  h('div', { style: card },
188
- h('div', { style: labelSt }, 'Current Deployment'),
203
+ h('div', { style: Object.assign({}, labelSt, { display: 'flex', alignItems: 'center' }) }, 'Current Deployment', h(HelpButton, { label: 'Current Deployment' },
204
+ h('p', null, 'This shows the URL you\'re currently accessing the dashboard from. This is where your team and agents connect.'),
205
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Share this URL with your team. If it shows localhost, you\'ll need to set up a tunnel or deploy to a server for external access.')
206
+ )),
189
207
  h('div', { style: { padding: '14px 16px', background: 'var(--bg-primary)', borderRadius: 'var(--radius)', display: 'flex', alignItems: 'center', justifyContent: 'space-between', border: '1px solid var(--border)', marginBottom: 12 } },
190
208
  h('span', { style: { fontSize: 15, fontFamily: 'var(--font-mono, monospace)', color: 'var(--accent)', wordBreak: 'break-all' } }, actualUrl),
191
209
  h('button', { className: 'btn btn-sm', onClick: function() { navigator.clipboard.writeText(actualUrl); toast('Copied!', 'success'); } }, 'Copy')
@@ -200,7 +218,10 @@ export function DomainStatusPage() {
200
218
  // ═══════════════════════════════════════════════
201
219
  h('div', { style: card },
202
220
  h('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 } },
203
- h('div', { style: labelSt }, 'AgenticMail Subdomain'),
221
+ h('div', { style: Object.assign({}, labelSt, { display: 'flex', alignItems: 'center' }) }, 'AgenticMail Subdomain', h(HelpButton, { label: 'AgenticMail Subdomain' },
222
+ h('p', null, 'A free subdomain on agenticmail.io (e.g., yourcompany.agenticmail.io). This gives you a public URL without needing your own domain.'),
223
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Changing the subdomain requires updating DNS records and any bookmarks or integrations that reference the old URL.')
224
+ )),
204
225
  !showEditSub && sub && h('button', { className: 'btn btn-sm', onClick: function() { setShowEditSub(true); setNewSub(sub || ''); setSubError(''); } }, 'Change')
205
226
  ),
206
227
 
@@ -268,7 +289,16 @@ export function DomainStatusPage() {
268
289
  h('div', { style: card },
269
290
  h('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 16 } },
270
291
  h('div', null,
271
- h('div', { style: labelSt }, 'Custom Domain'),
292
+ h('div', { style: Object.assign({}, labelSt, { display: 'flex', alignItems: 'center' }) }, 'Custom Domain', h(HelpButton, { label: 'Custom Domain' },
293
+ h('p', null, 'Use your own domain (e.g., agents.yourcompany.com) for a professional, branded deployment. Requires DNS verification to prove ownership.'),
294
+ h('h4', { style: _h4 }, 'Setup Process'),
295
+ h('ul', { style: _ul },
296
+ h('li', null, h('strong', null, 'Register'), ' — Enter your domain and get DNS challenge records.'),
297
+ h('li', null, h('strong', null, 'Add DNS records'), ' — Add TXT (verification) and CNAME/A (routing) records at your DNS provider.'),
298
+ h('li', null, h('strong', null, 'Verify'), ' — Click "Verify DNS Now" once records propagate (up to 48 hours).')
299
+ ),
300
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Use a subdomain like agents.yourcompany.com instead of the root domain — it\'s easier to set up and doesn\'t affect your main website.')
301
+ )),
272
302
  h('div', { style: { fontSize: 12, color: 'var(--text-muted)', marginTop: -6 } }, 'Deploy on your own domain — either a subdomain (agents.yourcompany.com) or root domain (yourcompany.com)')
273
303
  )
274
304
  ),
@@ -399,7 +429,15 @@ export function DomainStatusPage() {
399
429
  // ═══════════════════════════════════════════════
400
430
  h('div', { style: card },
401
431
  h('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 } },
402
- h('div', { style: labelSt }, 'Allowed Origins (CORS)'),
432
+ h('div', { style: Object.assign({}, labelSt, { display: 'flex', alignItems: 'center' }) }, 'Allowed Origins (CORS)', h(HelpButton, { label: 'Allowed Origins (CORS)' },
433
+ h('p', null, 'CORS (Cross-Origin Resource Sharing) controls which websites can make API requests to your AgenticMail server. This is a security measure to prevent unauthorized access.'),
434
+ h('h4', { style: _h4 }, 'What This Means'),
435
+ h('ul', { style: _ul },
436
+ h('li', null, h('strong', null, 'No origins listed'), ' — Any website can make API requests (open access). Fine for development, risky for production.'),
437
+ h('li', null, h('strong', null, 'Origins listed'), ' — Only those specific domains can make API requests.')
438
+ ),
439
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'CORS is auto-updated when you change your subdomain or custom domain. For manual control, go to Settings → Network & Firewall.')
440
+ )),
403
441
  h('a', { href: '/dashboard/settings#network', style: { fontSize: 12, color: 'var(--accent)', textDecoration: 'none', fontWeight: 500 } }, 'Manage in Settings \u2192')
404
442
  ),
405
443
  corsOrigins.length === 0
@@ -424,7 +462,10 @@ export function DomainStatusPage() {
424
462
  h('div', { style: { display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 } },
425
463
  h('span', { style: { fontSize: 20 } }, '\uD83D\uDCE6'),
426
464
  h('div', null,
427
- h('div', { style: { fontSize: 14, fontWeight: 700 } }, 'Migrate to Another Machine'),
465
+ h('div', { style: { fontSize: 14, fontWeight: 700, display: 'flex', alignItems: 'center' } }, 'Migrate to Another Machine', h(HelpButton, { label: 'Migration' },
466
+ h('p', null, 'Move your entire AgenticMail deployment to a different server or computer. All you need is the .env file — it contains all configuration and encryption keys.'),
467
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Always back up your .env file securely. Without the VAULT_KEY, encrypted credentials cannot be recovered.')
468
+ )),
428
469
  h('div', { style: { fontSize: 12, color: 'var(--text-muted)' } }, 'Move your entire deployment to a new server or computer')
429
470
  )
430
471
  ),
@@ -467,7 +508,10 @@ export function DomainStatusPage() {
467
508
  // CLI Reference
468
509
  // ═══════════════════════════════════════════════
469
510
  h('div', { style: card },
470
- h('div', { style: labelSt }, 'CLI Commands'),
511
+ h('div', { style: Object.assign({}, labelSt, { display: 'flex', alignItems: 'center' }) }, 'CLI Commands', h(HelpButton, { label: 'CLI Commands' },
512
+ h('p', null, 'Common command-line commands for managing your AgenticMail Enterprise installation. Run these in your terminal on the server where AgenticMail is installed.'),
513
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Use "npx @agenticmail/enterprise@latest" to always run the latest version without manually updating.')
514
+ )),
471
515
  h('div', { style: { display: 'grid', gap: 8 } },
472
516
  cliRow('Initial setup', 'npx @agenticmail/enterprise setup'),
473
517
  cliRow('Start server', 'npx @agenticmail/enterprise start'),
@@ -1,5 +1,6 @@
1
1
  import { h, useState, useEffect, useCallback, Fragment, useApp, engineCall, buildAgentEmailMap, resolveAgentEmail, buildAgentDataMap, renderAgentBadge, getOrgId } from '../components/utils.js';
2
2
  import { I } from '../components/icons.js';
3
+ import { HelpButton } from '../components/help-button.js';
3
4
 
4
5
  // ─── Constants ──────────────────────────────────────────
5
6
 
@@ -111,8 +112,23 @@ export function GuardrailsPage() {
111
112
  { id: 'rules', label: 'Rules & Interventions' },
112
113
  ];
113
114
 
115
+ var _h4 = { marginTop: 16, marginBottom: 8, fontSize: 14 };
116
+ var _ul = { paddingLeft: 20, margin: '4px 0 8px' };
117
+ var _tip = { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 };
118
+
114
119
  return h('div', { className: 'page-inner' },
115
- h('div', { className: 'page-header' }, h('h1', null, 'Guardrails & Intervention')),
120
+ h('div', { className: 'page-header' }, h('h1', { style: { display: 'flex', alignItems: 'center' } }, 'Guardrails & Intervention', h(HelpButton, { label: 'Guardrails & Intervention' },
121
+ h('p', null, 'Central control panel for agent safety. Define policies agents must follow, configure automated rules that trigger interventions, manage onboarding, and inspect agent memory.'),
122
+ h('h4', { style: _h4 }, 'Tabs overview'),
123
+ h('ul', { style: _ul },
124
+ h('li', null, h('strong', null, 'Overview'), ' — Quick stats, agent controls (pause/resume/kill), onboarding status, and recent interventions.'),
125
+ h('li', null, h('strong', null, 'Policies'), ' — Define behavioral rules agents must acknowledge and follow.'),
126
+ h('li', null, h('strong', null, 'Onboarding'), ' — Track which agents have acknowledged org policies.'),
127
+ h('li', null, h('strong', null, 'Agent Memory'), ' — View and manage what agents remember.'),
128
+ h('li', null, h('strong', null, 'Rules & Interventions'), ' — Automated guardrail rules, anomaly detection, and intervention history.')
129
+ ),
130
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Start with the Overview tab for a quick health check, then drill into specific tabs for detailed management.')
131
+ ))),
116
132
  h('div', { className: 'tabs', style: { marginBottom: 16 } },
117
133
  TABS.map(function(t) { return h('button', { key: t.id, className: 'tab' + (activeTab === t.id ? ' active' : ''), onClick: function() { setTab(t.id); } }, t.label); })
118
134
  ),
@@ -208,7 +224,14 @@ function OverviewTab(props) {
208
224
  ),
209
225
  // Onboarding progress summary
210
226
  onboardingData.length > 0 && h('div', { className: 'card', style: { marginBottom: 16 } },
211
- h('div', { className: 'card-header' }, h('h3', null, 'Agent Onboarding Status')),
227
+ h('div', { className: 'card-header' }, h('h3', { style: { display: 'flex', alignItems: 'center' } }, 'Agent Onboarding Status', h(HelpButton, { label: 'Agent Onboarding Status' },
228
+ h('p', null, 'Shows which agents have acknowledged your organization\'s policies. Agents must complete onboarding before they can operate fully.'),
229
+ h('ul', { style: { paddingLeft: 20, margin: '4px 0 8px' } },
230
+ h('li', null, h('strong', null, 'Green'), ' — Completed all required policy acknowledgments.'),
231
+ h('li', null, h('strong', null, 'Yellow'), ' — In progress, some policies still pending.'),
232
+ h('li', null, h('strong', null, 'Red'), ' — Needs renewal due to policy changes.')
233
+ )
234
+ ))),
212
235
  h('div', { className: 'card-body' },
213
236
  onboardingData.slice(0, 8).map(function(ag) {
214
237
  var statusColor = ag.overallStatus === 'completed' ? '#10b981' : ag.overallStatus === 'in_progress' ? '#f59e0b' : ag.overallStatus === 'needs_renewal' ? '#ef4444' : '#64748b';
@@ -223,7 +246,10 @@ function OverviewTab(props) {
223
246
  ),
224
247
  // Recent interventions
225
248
  h('div', { className: 'card' },
226
- h('div', { className: 'card-header' }, h('h3', null, 'Recent Interventions')),
249
+ h('div', { className: 'card-header' }, h('h3', { style: { display: 'flex', alignItems: 'center' } }, 'Recent Interventions', h(HelpButton, { label: 'Recent Interventions' },
250
+ h('p', null, 'Log of recent agent interventions — pauses, kills, and resumes. Shows what happened, which agent was affected, and who triggered it.'),
251
+ h('div', { style: { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 } }, h('strong', null, 'Tip: '), 'If an agent was paused by an automated rule, you can resume it directly from the Actions column.')
252
+ ))),
227
253
  interventions.length === 0
228
254
  ? h(EmptyState, { message: 'No interventions recorded' })
229
255
  : h('table', { className: 'data-table' },
@@ -1,5 +1,6 @@
1
1
  import { h, useState, useEffect, Fragment, useApp, engineCall, buildAgentEmailMap, buildAgentDataMap, resolveAgentEmail, renderAgentBadge, getOrgId } from '../components/utils.js';
2
2
  import { I } from '../components/icons.js';
3
+ import { HelpButton } from '../components/help-button.js';
3
4
 
4
5
  export function JournalPage() {
5
6
  const { toast } = useApp();
@@ -23,12 +24,31 @@ export function JournalPage() {
23
24
  try { const r = await engineCall('/journal/' + id + '/rollback', { method: 'POST', body: JSON.stringify({}) }); if (r.success) { toast('Action rolled back', 'success'); load(); } else toast('Rollback failed: ' + (r.error || 'Unknown'), 'error'); } catch (e) { toast(e.message, 'error'); }
24
25
  };
25
26
 
27
+ var _h4 = { marginTop: 16, marginBottom: 8, fontSize: 14 };
28
+ var _ul = { paddingLeft: 20, margin: '4px 0 8px' };
29
+ var _tip = { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 };
30
+
26
31
  return h('div', { className: 'page-inner' },
27
- h('div', { className: 'page-header' }, h('h1', null, 'Action Journal')),
32
+ h('div', { className: 'page-header' }, h('h1', { style: { display: 'flex', alignItems: 'center' } }, 'Action Journal', h(HelpButton, { label: 'Action Journal' },
33
+ h('p', null, 'A tamper-proof log of every action agents have taken. Think of it as an audit trail — every tool call, every side effect, recorded with full context.'),
34
+ h('h4', { style: _h4 }, 'Why it matters'),
35
+ h('ul', { style: _ul },
36
+ h('li', null, h('strong', null, 'Accountability'), ' — Know exactly what each agent did and when.'),
37
+ h('li', null, h('strong', null, 'Rollback'), ' — Reverse actions that were mistakes or caused issues.'),
38
+ h('li', null, h('strong', null, 'Compliance'), ' — Maintain a full audit trail for regulatory needs.')
39
+ ),
40
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Use the Rollback button on reversible actions to undo agent mistakes without manual intervention.')
41
+ ))),
28
42
  stats && h('div', { className: 'stat-grid', style: { marginBottom: 16 } },
29
- h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.total), h('div', { className: 'stat-label' }, 'Total Actions')),
30
- h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.reversible), h('div', { className: 'stat-label' }, 'Reversible')),
31
- h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.reversed), h('div', { className: 'stat-label' }, 'Rolled Back'))
43
+ h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.total), h('div', { className: 'stat-label', style: { display: 'flex', alignItems: 'center' } }, 'Total Actions', h(HelpButton, { label: 'Total Actions' },
44
+ h('p', null, 'The total number of tool calls and side effects recorded across all agents.')
45
+ ))),
46
+ h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.reversible), h('div', { className: 'stat-label', style: { display: 'flex', alignItems: 'center' } }, 'Reversible', h(HelpButton, { label: 'Reversible' },
47
+ h('p', null, 'Actions that can be undone (rolled back). Not all actions are reversible — for example, sent emails cannot be unsent.')
48
+ ))),
49
+ h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.reversed), h('div', { className: 'stat-label', style: { display: 'flex', alignItems: 'center' } }, 'Rolled Back', h(HelpButton, { label: 'Rolled Back' },
50
+ h('p', null, 'Actions that have been reversed by an admin. A high number may indicate agents need tighter permissions or better instructions.')
51
+ )))
32
52
  ),
33
53
  h('div', { className: 'card' },
34
54
  h('table', { className: 'data-table' },
@@ -267,7 +267,19 @@ export function KnowledgeContributionsPage() {
267
267
 
268
268
  return h(Fragment, null,
269
269
  h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 } },
270
- h('span', { style: { fontSize: 13, color: 'var(--text-muted)' } }, bases.length + ' knowledge base' + (bases.length !== 1 ? 's' : '')),
270
+ h('span', { style: { fontSize: 13, color: 'var(--text-muted)', display: 'flex', alignItems: 'center' } }, bases.length + ' knowledge base' + (bases.length !== 1 ? 's' : ''),
271
+ h(HelpButton, { label: 'Knowledge Bases' },
272
+ h('p', null, 'Each knowledge base is a searchable collection of documents. Agents use these to answer questions with real organizational data instead of guessing.'),
273
+ h('h4', { style: _h4 }, 'How It Works'),
274
+ h('ul', { style: _ul },
275
+ h('li', null, h('strong', null, 'Create'), ' a knowledge base and give it a descriptive name (e.g., "HR Policies", "Product Docs").'),
276
+ h('li', null, h('strong', null, 'Import'), ' documents via the Knowledge Import page — upload files, crawl URLs, or paste text.'),
277
+ h('li', null, h('strong', null, 'Assign'), ' the knowledge base to agents in their Deployment tab.'),
278
+ h('li', null, h('strong', null, 'Search'), ' happens automatically when agents use the knowledge_base_search tool.')
279
+ ),
280
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Click on a knowledge base to see its documents and chunks. Chunks are the small pieces of text that get matched during search — smaller chunks give more precise results.')
281
+ )
282
+ ),
271
283
  h('button', { className: 'btn btn-primary', onClick: function() { setShowCreateBase(true); } }, I.plus(), ' Create Knowledge Base')
272
284
  ),
273
285
  bases.length === 0
@@ -425,6 +437,21 @@ export function KnowledgeContributionsPage() {
425
437
  var agentData = buildAgentDataMap(agents);
426
438
 
427
439
  var renderContributions = function() {
440
+ // Header with help
441
+ var _contribHeader = h('div', { style: { display: 'flex', alignItems: 'center', gap: 4, marginBottom: 12 } },
442
+ h('span', { style: { fontSize: 14, fontWeight: 600 } }, 'Agent Contributions'),
443
+ h(HelpButton, { label: 'Agent Contributions' },
444
+ h('p', null, 'Every entry here is a piece of knowledge an agent contributed — a fact learned, a decision recorded, a process documented, or an insight captured during work.'),
445
+ h('h4', { style: _h4 }, 'Contribution Details'),
446
+ h('ul', { style: _ul },
447
+ h('li', null, h('strong', null, 'Confidence'), ' — How certain the agent is about this knowledge (0-100%). Higher confidence = more reliable. Contributions below your threshold are flagged for review.'),
448
+ h('li', null, h('strong', null, 'Category'), ' — The type of knowledge (fact, process, decision, preference, etc.). Helps organize and filter.'),
449
+ h('li', null, h('strong', null, 'Source'), ' — Where the agent learned this (conversation, email, document, etc.).')
450
+ ),
451
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Review low-confidence contributions periodically. You can edit, approve, or delete them. High-quality contributions improve all agents that share this knowledge base.')
452
+ )
453
+ );
454
+
428
455
  // Filter
429
456
  var filtered = contributions;
430
457
  if (contribAgent) filtered = filtered.filter(function(c) { return c.agentId === contribAgent; });
@@ -440,6 +467,7 @@ export function KnowledgeContributionsPage() {
440
467
  var paged = filtered.slice(contribPage * CONTRIB_PAGE_SIZE, (contribPage + 1) * CONTRIB_PAGE_SIZE);
441
468
 
442
469
  return h(Fragment, null,
470
+ _contribHeader,
443
471
  // Filter bar
444
472
  h('div', { style: { display: 'flex', gap: 10, marginBottom: 14, flexWrap: 'wrap', alignItems: 'center' } },
445
473
  h('input', {
@@ -506,7 +534,18 @@ export function KnowledgeContributionsPage() {
506
534
  var renderSchedules = function() {
507
535
  return h(Fragment, null,
508
536
  h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 } },
509
- h('span', { style: { fontSize: 13, color: 'var(--text-muted)' } }, schedules.length + ' schedule' + (schedules.length !== 1 ? 's' : '')),
537
+ h('span', { style: { fontSize: 13, color: 'var(--text-muted)', display: 'flex', alignItems: 'center' } }, schedules.length + ' schedule' + (schedules.length !== 1 ? 's' : ''),
538
+ h(HelpButton, { label: 'Contribution Schedules' },
539
+ h('p', null, 'Schedules automate knowledge contributions. Instead of relying on agents to contribute spontaneously, schedules trigger periodic knowledge synthesis.'),
540
+ h('h4', { style: _h4 }, 'How Schedules Work'),
541
+ h('ul', { style: _ul },
542
+ h('li', null, 'Pick an agent and a target knowledge base.'),
543
+ h('li', null, 'Set the frequency (hourly, daily, weekly, monthly) and a minimum confidence threshold.'),
544
+ h('li', null, 'At each interval, the agent reviews its recent memories and contributes relevant knowledge above the confidence threshold.')
545
+ ),
546
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Weekly schedules with 60%+ confidence work well for most use cases. Daily schedules generate more granular but potentially noisier contributions.')
547
+ )
548
+ ),
510
549
  h('button', { className: 'btn btn-primary', onClick: function() { setShowCreateSchedule(true); } }, I.plus(), ' Create Schedule')
511
550
  ),
512
551
  schedules.length === 0
@@ -1183,6 +1222,20 @@ export function KnowledgeContributionsPage() {
1183
1222
  var m = searchMetrics;
1184
1223
 
1185
1224
  return h('div', null,
1225
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: 4, marginBottom: 16 } },
1226
+ h('span', { style: { fontSize: 14, fontWeight: 600 } }, 'Search Metrics'),
1227
+ h(HelpButton, { label: 'Search Metrics' },
1228
+ h('p', null, 'Track how agents are searching your knowledge bases. This helps you understand which bases are useful and where there are gaps.'),
1229
+ h('h4', { style: _h4 }, 'Key Metrics'),
1230
+ h('ul', { style: _ul },
1231
+ h('li', null, h('strong', null, 'Total Searches'), ' — How many times agents searched knowledge bases in the selected period.'),
1232
+ h('li', null, h('strong', null, 'KB vs Hub Searches'), ' — KB searches target a specific knowledge base; Hub searches query across all bases.'),
1233
+ h('li', null, h('strong', null, 'Hit Rate'), ' — Percentage of searches that returned useful results. Low hit rates mean agents are searching for things not in your knowledge bases.'),
1234
+ h('li', null, h('strong', null, 'Avg Results'), ' — Average number of results per search. Too few = gaps in content; too many = content may be too broad.')
1235
+ ),
1236
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'If hit rate is low, check the "Top Queries with No Results" section to see what\'s missing from your knowledge bases, then import relevant content.')
1237
+ )
1238
+ ),
1186
1239
  // Filters
1187
1240
  h('div', { style: { display: 'flex', gap: 12, marginBottom: 20 } },
1188
1241
  h('select', {
@@ -1325,7 +1378,20 @@ export function KnowledgeContributionsPage() {
1325
1378
  // Header
1326
1379
  h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 } },
1327
1380
  h('div', null,
1328
- h('h1', { style: { fontSize: 20, fontWeight: 700 } }, 'Knowledge Contributions'),
1381
+ h('h1', { style: { fontSize: 20, fontWeight: 700, display: 'flex', alignItems: 'center' } }, 'Knowledge Contributions',
1382
+ h(HelpButton, { label: 'Knowledge Contributions' },
1383
+ h('p', null, 'This is where your agents build shared organizational knowledge. Agents contribute what they learn from conversations, tasks, and research into knowledge bases that all agents can search.'),
1384
+ h('h4', { style: _h4 }, 'Tabs'),
1385
+ h('ul', { style: _ul },
1386
+ h('li', null, h('strong', null, 'Knowledge Bases'), ' — Create and manage knowledge bases. Each is a collection of documents that agents can search via RAG (Retrieval-Augmented Generation).'),
1387
+ h('li', null, h('strong', null, 'Contributions'), ' — Browse individual knowledge entries that agents have contributed. Filter by agent, search by content, and review quality.'),
1388
+ h('li', null, h('strong', null, 'Schedules'), ' — Automate knowledge contributions on a schedule (e.g., weekly synthesis of learnings).'),
1389
+ h('li', null, h('strong', null, 'Stats'), ' — Charts showing contribution volume, confidence levels, category distribution, and agent quality over time.'),
1390
+ h('li', null, h('strong', null, 'Search Metrics'), ' — How agents are using knowledge search — query volume, hit rates, and which bases are most useful.')
1391
+ ),
1392
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Start by creating a knowledge base, then enable knowledge contributions in each agent\'s Autonomy settings. Agents will automatically contribute what they learn.')
1393
+ )
1394
+ ),
1329
1395
  h('p', { style: { color: 'var(--text-muted)', fontSize: 13 } },
1330
1396
  'Collaborative knowledge building from agent memories and experiences'
1331
1397
  )
@@ -12,6 +12,7 @@ import { h, useState, useEffect, useRef, Fragment, useApp, engineCall, getOrgId
12
12
  import { I } from '../components/icons.js';
13
13
  import { ProviderLogo } from '../assets/provider-logos.js';
14
14
  import { Modal } from '../components/modal.js';
15
+ import { HelpButton } from '../components/help-button.js';
15
16
 
16
17
  // ─── Platform Definitions ────────────────────────────
17
18
 
@@ -421,7 +422,11 @@ export function ImportJobsList({ kbId }) {
421
422
 
422
423
  return h('div', { className: 'card', style: { marginTop: 16 } },
423
424
  h('div', { className: 'card-header' },
424
- h('h3', { style: { margin: 0, fontSize: 14 } }, 'Import History'),
425
+ h('h3', { style: { margin: 0, fontSize: 14, display: 'flex', alignItems: 'center' } }, 'Import History', h(HelpButton, { label: 'Import History' },
426
+ h('p', null, 'Shows all previous import jobs for this knowledge base. Track the status, source, and results of each import.'),
427
+ h('p', null, h('strong', null, 'Statuses: '), 'completed (all documents imported), running (in progress), failed (error occurred), cancelled (manually stopped).'),
428
+ h('p', { style: { marginTop: 8, padding: 8, background: 'var(--bg-secondary, #1e293b)', borderRadius: 6, fontSize: 13 } }, h('strong', null, 'Tip: '), 'If an import fails, check the source URL and credentials, then try again.')
429
+ )),
425
430
  ),
426
431
  h('div', { className: 'card-body-flush' },
427
432
  h('table', null,
@@ -2,6 +2,7 @@ import { h, useState, useEffect, useCallback, Fragment, useApp, engineCall, getO
2
2
  import { I } from '../components/icons.js';
3
3
  import { Modal } from '../components/modal.js';
4
4
  import { KnowledgeImportWizard, ImportJobsList } from './knowledge-import.js';
5
+ import { HelpButton } from '../components/help-button.js';
5
6
 
6
7
  export function KnowledgeBasePage() {
7
8
  const { toast } = useApp();
@@ -120,6 +121,10 @@ export function KnowledgeBasePage() {
120
121
  } catch (e) { toast(e.message, 'error'); }
121
122
  };
122
123
 
124
+ var _h4 = { marginTop: 16, marginBottom: 8, fontSize: 14 };
125
+ var _ul = { paddingLeft: 20, margin: '4px 0 8px' };
126
+ var _tip = { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 };
127
+
123
128
  // ── Detail View ──
124
129
  if (selected) {
125
130
  return h(Fragment, null,
@@ -128,7 +133,16 @@ export function KnowledgeBasePage() {
128
133
  h('button', { className: 'btn btn-secondary btn-sm', onClick: () => setSelected(null) }, '\u2190 Back'),
129
134
  editing
130
135
  ? h('input', { className: 'input', value: editForm.name, onChange: e => setEditForm(f => ({ ...f, name: e.target.value })), style: { fontSize: 18, fontWeight: 700, padding: '4px 8px' } })
131
- : h('h1', { style: { fontSize: 20, fontWeight: 700, margin: 0 } }, selected.name)
136
+ : h('h1', { style: { fontSize: 20, fontWeight: 700, margin: 0, display: 'flex', alignItems: 'center' } }, selected.name, h(HelpButton, { label: 'Knowledge Base Detail' },
137
+ h('p', null, 'This is the detail view for a single knowledge base. Here you can manage documents, view chunks, and import new content.'),
138
+ h('h4', { style: _h4 }, 'Key Actions'),
139
+ h('ul', { style: _ul },
140
+ h('li', null, h('strong', null, 'Import Docs'), ' — Add documents from GitHub, Google Drive, websites, or file uploads.'),
141
+ h('li', null, h('strong', null, 'Edit'), ' — Rename or update the description of this knowledge base.'),
142
+ h('li', null, h('strong', null, 'Delete'), ' — Permanently remove this knowledge base and all its documents.')
143
+ ),
144
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Click a document on the left to preview its chunks on the right. You can edit individual chunks for fine-grained control.')
145
+ ))
132
146
  ),
133
147
  h('div', { style: { display: 'flex', gap: 8 } },
134
148
  editing
@@ -162,13 +176,13 @@ export function KnowledgeBasePage() {
162
176
  // Stats
163
177
  selected.stats && h('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 12, marginBottom: 16 } },
164
178
  [
165
- { label: 'Documents', value: selected.stats?.documentCount || selected.stats?.documents || selected.stats?.totalDocuments || docs.length },
166
- { label: 'Chunks', value: selected.stats?.chunkCount || selected.stats?.chunks || selected.stats?.totalChunks || 0 },
167
- { label: 'Total Tokens', value: selected.stats?.totalTokens || 0 },
168
- { label: 'Queries', value: selected.stats?.queryCount || 0 },
179
+ { label: 'Documents', value: selected.stats?.documentCount || selected.stats?.documents || selected.stats?.totalDocuments || docs.length, help: 'Total number of source documents imported into this knowledge base.' },
180
+ { label: 'Chunks', value: selected.stats?.chunkCount || selected.stats?.chunks || selected.stats?.totalChunks || 0, help: 'Total text segments created from your documents. More chunks = more granular retrieval.' },
181
+ { label: 'Total Tokens', value: selected.stats?.totalTokens || 0, help: 'Total token count across all chunks. This affects storage costs and retrieval context size.' },
182
+ { label: 'Queries', value: selected.stats?.queryCount || 0, help: 'Number of times agents have searched this knowledge base. Higher usage means this KB is valuable.' },
169
183
  ].map(s => h('div', { key: s.label, className: 'card', style: { textAlign: 'center', padding: 12 } },
170
184
  h('div', { style: { fontSize: 22, fontWeight: 700, color: 'var(--brand-color, #6366f1)' } }, typeof s.value === 'number' && s.value > 1000 ? (s.value / 1000).toFixed(1) + 'K' : s.value),
171
- h('div', { style: { fontSize: 12, color: 'var(--text-muted)', marginTop: 2 } }, s.label)
185
+ h('div', { style: { fontSize: 12, color: 'var(--text-muted)', marginTop: 2, display: 'flex', alignItems: 'center', justifyContent: 'center' } }, s.label, h(HelpButton, { label: s.label }, h('p', null, s.help)))
172
186
  ))
173
187
  ),
174
188
 
@@ -179,7 +193,16 @@ export function KnowledgeBasePage() {
179
193
  h('div', { className: 'card' },
180
194
  h('div', { className: 'card-header' },
181
195
  h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
182
- h('h3', { style: { margin: 0 } }, 'Documents'),
196
+ h('h3', { style: { margin: 0, display: 'flex', alignItems: 'center' } }, 'Documents', h(HelpButton, { label: 'Documents' },
197
+ h('p', null, 'Documents are the source files you\'ve imported into this knowledge base. Each document is automatically split into smaller chunks for efficient retrieval.'),
198
+ h('h4', { style: _h4 }, 'Managing Documents'),
199
+ h('ul', { style: _ul },
200
+ h('li', null, h('strong', null, 'Click'), ' a document to view its chunks in the right panel.'),
201
+ h('li', null, h('strong', null, 'Rename'), ' — Click the edit icon to rename a document.'),
202
+ h('li', null, h('strong', null, 'Delete'), ' — Remove a document and all its chunks.')
203
+ ),
204
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Use "Import Docs" to add more documents from various sources like GitHub, Google Drive, or direct file upload.')
205
+ )),
183
206
  h('span', { className: 'badge badge-neutral' }, docs.length)
184
207
  )
185
208
  ),
@@ -218,7 +241,16 @@ export function KnowledgeBasePage() {
218
241
  // Chunk preview
219
242
  h('div', { className: 'card' },
220
243
  h('div', { className: 'card-header' },
221
- h('h3', { style: { margin: 0 } }, selectedDoc ? 'Chunks: ' + (selectedDoc.name || selectedDoc.id) : 'Select a document')
244
+ h('h3', { style: { margin: 0, display: 'flex', alignItems: 'center' } }, selectedDoc ? 'Chunks: ' + (selectedDoc.name || selectedDoc.id) : 'Select a document', h(HelpButton, { label: 'Chunks' },
245
+ h('p', null, 'Chunks are the smaller text segments that documents are split into for RAG (Retrieval-Augmented Generation). When an agent queries the knowledge base, the most relevant chunks are retrieved and included in the prompt.'),
246
+ h('h4', { style: _h4 }, 'Why Chunks Matter'),
247
+ h('ul', { style: _ul },
248
+ h('li', null, h('strong', null, 'Granularity'), ' — Smaller chunks allow more precise retrieval of relevant information.'),
249
+ h('li', null, h('strong', null, 'Token count'), ' — Each chunk has a token count that affects how much context is used.'),
250
+ h('li', null, h('strong', null, 'Editing'), ' — You can manually edit chunks to improve quality or fix errors.')
251
+ ),
252
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'If an agent gives incorrect answers, check the relevant chunks — you may need to edit them for clarity or accuracy.')
253
+ ))
222
254
  ),
223
255
  h('div', { className: 'card-body', style: { maxHeight: 500, overflow: 'auto' } },
224
256
  !selectedDoc
@@ -267,7 +299,17 @@ export function KnowledgeBasePage() {
267
299
  return h(Fragment, null,
268
300
  h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 } },
269
301
  h('div', null,
270
- h('h1', { style: { fontSize: 20, fontWeight: 700 } }, 'Knowledge Bases'),
302
+ h('h1', { style: { fontSize: 20, fontWeight: 700, display: 'flex', alignItems: 'center' } }, 'Knowledge Bases', h(HelpButton, { label: 'Knowledge Bases' },
303
+ h('p', null, 'Knowledge bases store documents that your agents can search and reference when answering questions. This is the foundation of RAG (Retrieval-Augmented Generation).'),
304
+ h('h4', { style: _h4 }, 'How It Works'),
305
+ h('ul', { style: _ul },
306
+ h('li', null, h('strong', null, 'Create'), ' a knowledge base to organize related documents together.'),
307
+ h('li', null, h('strong', null, 'Import'), ' documents from GitHub, Google Drive, SharePoint, websites, or file uploads.'),
308
+ h('li', null, h('strong', null, 'Assign'), ' knowledge bases to agents so they can search and retrieve relevant information.'),
309
+ h('li', null, h('strong', null, 'Query'), ' — When an agent needs information, it searches the knowledge base and retrieves the most relevant chunks.')
310
+ ),
311
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Organize knowledge bases by topic or department. Smaller, focused knowledge bases often produce better search results than one large one.')
312
+ )),
271
313
  h('p', { style: { color: 'var(--text-muted)', fontSize: 13 } }, 'Document ingestion and RAG retrieval for agents')
272
314
  ),
273
315
  h('button', { className: 'btn btn-primary', onClick: () => setCreating(true) }, I.plus(), ' New Knowledge Base')
@@ -1,5 +1,6 @@
1
1
  import { h, useState, useEffect, useRef, Fragment, useApp, engineCall, buildAgentEmailMap, resolveAgentEmail, buildAgentDataMap, renderAgentBadge, getOrgId } from '../components/utils.js';
2
2
  import { I } from '../components/icons.js';
3
+ import { HelpButton } from '../components/help-button.js';
3
4
 
4
5
  export function MessagesPage() {
5
6
  const { toast } = useApp();
@@ -194,16 +195,38 @@ export function MessagesPage() {
194
195
  );
195
196
  };
196
197
 
198
+ var _h4 = { marginTop: 16, marginBottom: 8, fontSize: 14 };
199
+ var _ul = { paddingLeft: 20, margin: '4px 0 8px' };
200
+ var _tip = { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 };
201
+
197
202
  return h('div', { className: 'page-inner' },
198
203
  // Page header
199
- h('div', { className: 'page-header' }, h('h1', null, 'Agent Messages'), h('button', { className: 'btn btn-primary', onClick: () => setShowModal(true) }, I.plus(), ' New Message')),
204
+ h('div', { className: 'page-header' }, h('h1', { style: { display: 'flex', alignItems: 'center' } }, 'Agent Messages', h(HelpButton, { label: 'Agent Messages' },
205
+ h('p', null, 'All inter-agent and external communications in one place. See how your agents talk to each other and to the outside world.'),
206
+ h('h4', { style: _h4 }, 'Message types'),
207
+ h('ul', { style: _ul },
208
+ h('li', null, h('strong', null, 'Internal'), ' — Agent-to-agent messages within your organization.'),
209
+ h('li', null, h('strong', null, 'External'), ' — Messages sent to or received from outside (email, APIs, etc.).'),
210
+ h('li', null, h('strong', null, 'Tasks/Handoffs'), ' — Structured work delegation between agents.'),
211
+ h('li', null, h('strong', null, 'Broadcasts'), ' — One-to-many announcements.')
212
+ ),
213
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Switch to the Topology tab to visualize which agents communicate most. Click nodes to see communication details.')
214
+ )), h('button', { className: 'btn btn-primary', onClick: () => setShowModal(true) }, I.plus(), ' New Message')),
200
215
 
201
216
  // Stats cards
202
217
  h('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(160px, 1fr))', gap: 12, marginBottom: 20 } },
203
- h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.totalMessages), h('div', { className: 'stat-label' }, 'Total')),
204
- h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.internalMessages), h('div', { className: 'stat-label' }, 'Internal')),
205
- h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.externalOutbound), h('div', { className: 'stat-label' }, 'External Out')),
206
- h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.externalInbound), h('div', { className: 'stat-label' }, 'External In'))
218
+ h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.totalMessages), h('div', { className: 'stat-label', style: { display: 'flex', alignItems: 'center' } }, 'Total', h(HelpButton, { label: 'Total Messages' },
219
+ h('p', null, 'The total count of all messages across all directions and types.')
220
+ ))),
221
+ h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.internalMessages), h('div', { className: 'stat-label', style: { display: 'flex', alignItems: 'center' } }, 'Internal', h(HelpButton, { label: 'Internal Messages' },
222
+ h('p', null, 'Messages exchanged between agents within your organization. High internal traffic usually means healthy collaboration.')
223
+ ))),
224
+ h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.externalOutbound), h('div', { className: 'stat-label', style: { display: 'flex', alignItems: 'center' } }, 'External Out', h(HelpButton, { label: 'External Outbound' },
225
+ h('p', null, 'Messages sent by agents to external recipients (customers, partners, APIs). Monitor this to ensure agents aren\'t over-communicating.')
226
+ ))),
227
+ h('div', { className: 'stat-card' }, h('div', { className: 'stat-value' }, stats.externalInbound), h('div', { className: 'stat-label', style: { display: 'flex', alignItems: 'center' } }, 'External In', h(HelpButton, { label: 'External Inbound' },
228
+ h('p', null, 'Messages received from outside your organization. These trigger agent workflows and responses.')
229
+ )))
207
230
  ),
208
231
 
209
232
  // Main tabs: Messages | Topology
@@ -1,5 +1,6 @@
1
1
  import { h, useState, useEffect, useCallback, useRef, Fragment, useApp, engineCall, getOrgId } from '../components/utils.js';
2
2
  import { I } from '../components/icons.js';
3
+ import { HelpButton } from '../components/help-button.js';
3
4
 
4
5
  // ─── Layout Constants ────────────────────────────────────
5
6
  const NODE_W = 220;
@@ -297,7 +298,23 @@ export function OrgChartPage() {
297
298
  return h('div', { style: { height: '100%', display: 'flex', flexDirection: 'column', background: BG, borderRadius: 'var(--radius-lg)', overflow: 'hidden' } },
298
299
  // Toolbar
299
300
  h('div', { style: { display: 'flex', alignItems: 'center', gap: 12, padding: '12px 20px', borderBottom: '1px solid rgba(255,255,255,0.08)', background: 'rgba(0,0,0,0.3)', flexShrink: 0 } },
300
- h('div', { style: { fontWeight: 700, fontSize: 16, color: '#fff' } }, 'Organization Chart'),
301
+ h('div', { style: { fontWeight: 700, fontSize: 16, color: '#fff', display: 'flex', alignItems: 'center' } }, 'Organization Chart', h(HelpButton, { label: 'Organization Chart' },
302
+ h('p', null, 'Visual hierarchy of all agents in your organization. Shows reporting relationships, status, and activity at a glance.'),
303
+ h('h4', { style: { marginTop: 16, marginBottom: 8, fontSize: 14 } }, 'Interactions'),
304
+ h('ul', { style: { paddingLeft: 20, margin: '4px 0 8px' } },
305
+ h('li', null, h('strong', null, 'Hover'), ' — Highlights the agent\'s full chain (managers above, reports below) and shows a detail tooltip.'),
306
+ h('li', null, h('strong', null, 'Scroll'), ' — Zoom in/out.'),
307
+ h('li', null, h('strong', null, 'Click & drag'), ' — Pan the canvas.'),
308
+ h('li', null, h('strong', null, 'Fit'), ' — Auto-zoom to fit all agents in view.')
309
+ ),
310
+ h('h4', { style: { marginTop: 16, marginBottom: 8, fontSize: 14 } }, 'Node badges'),
311
+ h('ul', { style: { paddingLeft: 20, margin: '4px 0 8px' } },
312
+ h('li', null, h('strong', null, 'MGR'), ' — This agent manages other agents.'),
313
+ h('li', null, h('strong', null, 'N tasks'), ' — Currently active tasks.'),
314
+ h('li', null, h('strong', null, 'N err'), ' — Errors recorded today.')
315
+ ),
316
+ h('div', { style: { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 } }, h('strong', null, 'Tip: '), 'Purple nodes represent external (human) managers. Configure manager relationships in each agent\'s settings.')
317
+ )),
301
318
  h('div', { style: { color: 'rgba(255,255,255,0.4)', fontSize: 13 } }, positioned.length + ' agents'),
302
319
  h('div', { style: { flex: 1 } }),
303
320
  // Legend