@agenticmail/enterprise 0.5.199 → 0.5.201

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 (110) hide show
  1. package/dist/agent-heartbeat-EGMBRD3R.js +510 -0
  2. package/dist/chunk-5C3SCMY5.js +4457 -0
  3. package/dist/chunk-6OZYUTPL.js +1224 -0
  4. package/dist/chunk-ZR4Z42HT.js +3679 -0
  5. package/dist/cli-agent-PLMDHMRR.js +1602 -0
  6. package/dist/cli-serve-PLBAWN7N.js +114 -0
  7. package/dist/cli.js +3 -3
  8. package/dist/dashboard/app.js +3 -0
  9. package/dist/dashboard/components/icons.js +1 -0
  10. package/dist/dashboard/pages/activity.js +14 -1
  11. package/dist/dashboard/pages/agent-detail/activity.js +17 -1
  12. package/dist/dashboard/pages/agent-detail/autonomy.js +17 -1
  13. package/dist/dashboard/pages/agent-detail/budget.js +25 -2
  14. package/dist/dashboard/pages/agent-detail/channels.js +10 -1
  15. package/dist/dashboard/pages/agent-detail/communication.js +10 -1
  16. package/dist/dashboard/pages/agent-detail/configuration.js +42 -1
  17. package/dist/dashboard/pages/agent-detail/deployment.js +147 -16
  18. package/dist/dashboard/pages/agent-detail/email.js +10 -1
  19. package/dist/dashboard/pages/agent-detail/guardrails.js +27 -3
  20. package/dist/dashboard/pages/agent-detail/manager.js +15 -1
  21. package/dist/dashboard/pages/agent-detail/meeting-browser.js +14 -2
  22. package/dist/dashboard/pages/agent-detail/memory.js +24 -5
  23. package/dist/dashboard/pages/agent-detail/overview.js +159 -21
  24. package/dist/dashboard/pages/agent-detail/permissions.js +28 -7
  25. package/dist/dashboard/pages/agent-detail/personal-details.js +17 -1
  26. package/dist/dashboard/pages/agent-detail/security.js +21 -5
  27. package/dist/dashboard/pages/agent-detail/skills-section.js +9 -1
  28. package/dist/dashboard/pages/agent-detail/tool-security.js +35 -8
  29. package/dist/dashboard/pages/agent-detail/tools.js +10 -1
  30. package/dist/dashboard/pages/agent-detail/whatsapp.js +11 -1
  31. package/dist/dashboard/pages/agent-detail/workforce.js +19 -4
  32. package/dist/dashboard/pages/agents.js +15 -1
  33. package/dist/dashboard/pages/approvals.js +15 -1
  34. package/dist/dashboard/pages/audit.js +23 -1
  35. package/dist/dashboard/pages/compliance.js +24 -2
  36. package/dist/dashboard/pages/dashboard.js +25 -6
  37. package/dist/dashboard/pages/dlp.js +23 -2
  38. package/dist/dashboard/pages/domain-status.js +51 -7
  39. package/dist/dashboard/pages/guardrails.js +29 -3
  40. package/dist/dashboard/pages/journal.js +24 -4
  41. package/dist/dashboard/pages/knowledge-contributions.js +69 -3
  42. package/dist/dashboard/pages/knowledge-import.js +6 -1
  43. package/dist/dashboard/pages/knowledge.js +51 -9
  44. package/dist/dashboard/pages/messages.js +28 -5
  45. package/dist/dashboard/pages/org-chart.js +18 -1
  46. package/dist/dashboard/pages/settings.js +30 -6
  47. package/dist/dashboard/pages/skill-connections.js +18 -4
  48. package/dist/dashboard/pages/skills.js +11 -1
  49. package/dist/dashboard/pages/task-pipeline.js +455 -0
  50. package/dist/dashboard/pages/users.js +14 -1
  51. package/dist/dashboard/pages/vault.js +22 -2
  52. package/dist/dashboard/pages/workforce.js +17 -1
  53. package/dist/index.js +3 -3
  54. package/dist/routes-KHABOHOV.js +13273 -0
  55. package/dist/runtime-6WFHCG3N.js +45 -0
  56. package/dist/server-BENJQHTB.js +15 -0
  57. package/dist/setup-7RQIFV5Y.js +20 -0
  58. package/package.json +1 -1
  59. package/src/dashboard/HELP-TOOLTIPS-GUIDE.md +45 -0
  60. package/src/dashboard/app.js +3 -0
  61. package/src/dashboard/components/icons.js +1 -0
  62. package/src/dashboard/pages/activity.js +14 -1
  63. package/src/dashboard/pages/agent-detail/activity.js +17 -1
  64. package/src/dashboard/pages/agent-detail/autonomy.js +17 -1
  65. package/src/dashboard/pages/agent-detail/budget.js +25 -2
  66. package/src/dashboard/pages/agent-detail/channels.js +10 -1
  67. package/src/dashboard/pages/agent-detail/communication.js +10 -1
  68. package/src/dashboard/pages/agent-detail/configuration.js +42 -1
  69. package/src/dashboard/pages/agent-detail/deployment.js +147 -16
  70. package/src/dashboard/pages/agent-detail/email.js +10 -1
  71. package/src/dashboard/pages/agent-detail/guardrails.js +27 -3
  72. package/src/dashboard/pages/agent-detail/manager.js +15 -1
  73. package/src/dashboard/pages/agent-detail/meeting-browser.js +14 -2
  74. package/src/dashboard/pages/agent-detail/memory.js +24 -5
  75. package/src/dashboard/pages/agent-detail/overview.js +159 -21
  76. package/src/dashboard/pages/agent-detail/permissions.js +28 -7
  77. package/src/dashboard/pages/agent-detail/personal-details.js +17 -1
  78. package/src/dashboard/pages/agent-detail/security.js +21 -5
  79. package/src/dashboard/pages/agent-detail/skills-section.js +9 -1
  80. package/src/dashboard/pages/agent-detail/tool-security.js +35 -8
  81. package/src/dashboard/pages/agent-detail/tools.js +10 -1
  82. package/src/dashboard/pages/agent-detail/whatsapp.js +11 -1
  83. package/src/dashboard/pages/agent-detail/workforce.js +19 -4
  84. package/src/dashboard/pages/agents.js +15 -1
  85. package/src/dashboard/pages/approvals.js +15 -1
  86. package/src/dashboard/pages/audit.js +23 -1
  87. package/src/dashboard/pages/compliance.js +24 -2
  88. package/src/dashboard/pages/dashboard.js +25 -6
  89. package/src/dashboard/pages/dlp.js +23 -2
  90. package/src/dashboard/pages/domain-status.js +51 -7
  91. package/src/dashboard/pages/guardrails.js +29 -3
  92. package/src/dashboard/pages/journal.js +24 -4
  93. package/src/dashboard/pages/knowledge-contributions.js +69 -3
  94. package/src/dashboard/pages/knowledge-import.js +6 -1
  95. package/src/dashboard/pages/knowledge.js +51 -9
  96. package/src/dashboard/pages/messages.js +28 -5
  97. package/src/dashboard/pages/org-chart.js +18 -1
  98. package/src/dashboard/pages/settings.js +30 -6
  99. package/src/dashboard/pages/skill-connections.js +18 -4
  100. package/src/dashboard/pages/skills.js +11 -1
  101. package/src/dashboard/pages/task-pipeline.js +455 -0
  102. package/src/dashboard/pages/users.js +14 -1
  103. package/src/dashboard/pages/vault.js +22 -2
  104. package/src/dashboard/pages/workforce.js +17 -1
  105. package/src/engine/model-fallback.ts +141 -0
  106. package/src/engine/routes.ts +5 -0
  107. package/src/engine/task-queue-after-spawn.ts +66 -0
  108. package/src/engine/task-queue-before-spawn.ts +109 -0
  109. package/src/engine/task-queue-routes.ts +133 -0
  110. package/src/engine/task-queue.ts +369 -0
@@ -0,0 +1,114 @@
1
+ import "./chunk-KFQGP6VL.js";
2
+
3
+ // src/cli-serve.ts
4
+ import { existsSync, readFileSync } from "fs";
5
+ import { join } from "path";
6
+ import { homedir } from "os";
7
+ function loadEnvFile() {
8
+ const candidates = [
9
+ join(process.cwd(), ".env"),
10
+ join(homedir(), ".agenticmail", ".env")
11
+ ];
12
+ for (const envPath of candidates) {
13
+ if (!existsSync(envPath)) continue;
14
+ try {
15
+ const content = readFileSync(envPath, "utf8");
16
+ for (const line of content.split("\n")) {
17
+ const trimmed = line.trim();
18
+ if (!trimmed || trimmed.startsWith("#")) continue;
19
+ const eq = trimmed.indexOf("=");
20
+ if (eq < 0) continue;
21
+ const key = trimmed.slice(0, eq).trim();
22
+ let val = trimmed.slice(eq + 1).trim();
23
+ if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
24
+ val = val.slice(1, -1);
25
+ }
26
+ if (!process.env[key]) process.env[key] = val;
27
+ }
28
+ console.log(`Loaded config from ${envPath}`);
29
+ return;
30
+ } catch {
31
+ }
32
+ }
33
+ }
34
+ async function ensureSecrets() {
35
+ const { randomUUID } = await import("crypto");
36
+ const envDir = join(homedir(), ".agenticmail");
37
+ const envPath = join(envDir, ".env");
38
+ let dirty = false;
39
+ if (!process.env.JWT_SECRET) {
40
+ process.env.JWT_SECRET = randomUUID() + randomUUID();
41
+ dirty = true;
42
+ console.log("[startup] Generated new JWT_SECRET (existing sessions will need to re-login)");
43
+ }
44
+ if (!process.env.AGENTICMAIL_VAULT_KEY) {
45
+ process.env.AGENTICMAIL_VAULT_KEY = randomUUID() + randomUUID();
46
+ dirty = true;
47
+ console.log("[startup] Generated new AGENTICMAIL_VAULT_KEY");
48
+ console.log("[startup] \u26A0\uFE0F Previously encrypted credentials will need to be re-entered in the dashboard");
49
+ }
50
+ if (dirty) {
51
+ try {
52
+ if (!existsSync(envDir)) {
53
+ const { mkdirSync } = await import("fs");
54
+ mkdirSync(envDir, { recursive: true });
55
+ }
56
+ const { appendFileSync } = await import("fs");
57
+ const lines = [];
58
+ let existing = "";
59
+ if (existsSync(envPath)) {
60
+ existing = readFileSync(envPath, "utf8");
61
+ }
62
+ if (!existing.includes("JWT_SECRET=")) {
63
+ lines.push(`JWT_SECRET=${process.env.JWT_SECRET}`);
64
+ }
65
+ if (!existing.includes("AGENTICMAIL_VAULT_KEY=")) {
66
+ lines.push(`AGENTICMAIL_VAULT_KEY=${process.env.AGENTICMAIL_VAULT_KEY}`);
67
+ }
68
+ if (lines.length) {
69
+ appendFileSync(envPath, "\n" + lines.join("\n") + "\n", { mode: 384 });
70
+ console.log(`[startup] Saved secrets to ${envPath}`);
71
+ }
72
+ } catch (e) {
73
+ console.warn(`[startup] Could not save secrets to ${envPath}: ${e.message}`);
74
+ }
75
+ }
76
+ }
77
+ async function runServe(_args) {
78
+ loadEnvFile();
79
+ const DATABASE_URL = process.env.DATABASE_URL;
80
+ const PORT = parseInt(process.env.PORT || "8080", 10);
81
+ await ensureSecrets();
82
+ const JWT_SECRET = process.env.JWT_SECRET;
83
+ const VAULT_KEY = process.env.AGENTICMAIL_VAULT_KEY;
84
+ if (!DATABASE_URL) {
85
+ console.error("ERROR: DATABASE_URL is required.");
86
+ console.error("");
87
+ console.error("Set it via environment variable or .env file:");
88
+ console.error(" DATABASE_URL=postgresql://user:pass@host:5432/db npx @agenticmail/enterprise start");
89
+ console.error("");
90
+ console.error("Or create a .env file (in cwd or ~/.agenticmail/.env):");
91
+ console.error(" DATABASE_URL=postgresql://user:pass@host:5432/db");
92
+ console.error(" JWT_SECRET=your-secret-here");
93
+ console.error(" PORT=3200");
94
+ process.exit(1);
95
+ }
96
+ const { createAdapter } = await import("./factory-K32DV2DR.js");
97
+ const { createServer } = await import("./server-BENJQHTB.js");
98
+ const db = await createAdapter({
99
+ type: DATABASE_URL.startsWith("postgres") ? "postgres" : "sqlite",
100
+ connectionString: DATABASE_URL
101
+ });
102
+ await db.migrate();
103
+ const server = createServer({
104
+ port: PORT,
105
+ db,
106
+ jwtSecret: JWT_SECRET,
107
+ corsOrigins: ["*"]
108
+ });
109
+ await server.start();
110
+ console.log(`AgenticMail Enterprise server running on :${PORT}`);
111
+ }
112
+ export {
113
+ runServe
114
+ };
package/dist/cli.js CHANGED
@@ -53,14 +53,14 @@ Skill Development:
53
53
  break;
54
54
  case "serve":
55
55
  case "start":
56
- import("./cli-serve-LGKXTAZ3.js").then((m) => m.runServe(args.slice(1))).catch(fatal);
56
+ import("./cli-serve-PLBAWN7N.js").then((m) => m.runServe(args.slice(1))).catch(fatal);
57
57
  break;
58
58
  case "agent":
59
- import("./cli-agent-XYXSRD2Q.js").then((m) => m.runAgent(args.slice(1))).catch(fatal);
59
+ import("./cli-agent-PLMDHMRR.js").then((m) => m.runAgent(args.slice(1))).catch(fatal);
60
60
  break;
61
61
  case "setup":
62
62
  default:
63
- import("./setup-FE3TBZIZ.js").then((m) => m.runSetupWizard()).catch(fatal);
63
+ import("./setup-7RQIFV5Y.js").then((m) => m.runSetupWizard()).catch(fatal);
64
64
  break;
65
65
  }
66
66
  function fatal(err) {
@@ -25,6 +25,7 @@ import { KnowledgeContributionsPage } from './pages/knowledge-contributions.js';
25
25
  import { SkillConnectionsPage } from './pages/skill-connections.js';
26
26
  import { VaultPage } from './pages/vault.js';
27
27
  import { OrgChartPage } from './pages/org-chart.js';
28
+ import { TaskPipelinePage } from './pages/task-pipeline.js';
28
29
 
29
30
  // ─── Toast System ────────────────────────────────────────
30
31
  let toastId = 0;
@@ -161,6 +162,7 @@ function App() {
161
162
  ]},
162
163
  { section: 'Management', items: [
163
164
  { id: 'org-chart', icon: I.orgChart, label: 'Org Chart' },
165
+ { id: 'task-pipeline', icon: I.workflow, label: 'Task Pipeline' },
164
166
  { id: 'workforce', icon: I.clock, label: 'Workforce' },
165
167
  { id: 'messages', icon: I.messages, label: 'Messages' },
166
168
  { id: 'guardrails', icon: I.guardrails, label: 'Guardrails' },
@@ -199,6 +201,7 @@ function App() {
199
201
  'skill-connections': SkillConnectionsPage,
200
202
  vault: VaultPage,
201
203
  'org-chart': OrgChartPage,
204
+ 'task-pipeline': TaskPipelinePage,
202
205
  };
203
206
 
204
207
  const navigateToAgent = (agentId) => { _setSelectedAgentId(agentId); history.pushState(null, '', '/dashboard/agents/' + agentId); };
@@ -43,6 +43,7 @@ export const I = {
43
43
  link: () => h('svg', S, h('path', { d: 'M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71' }), h('path', { d: 'M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71' })),
44
44
  folder: () => h('svg', S, h('path', { d: 'M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z' })),
45
45
  globe: () => h('svg', S, h('circle', { cx: 12, cy: 12, r: 10 }), h('line', { x1: 2, y1: 12, x2: 22, y2: 12 }), h('path', { d: 'M12 2a15.3 15.3 0 014 10 15.3 15.3 0 01-4 10 15.3 15.3 0 01-4-10 15.3 15.3 0 014-10z' })),
46
+ workflow: () => h('svg', S, h('rect', { x: 3, y: 3, width: 6, height: 6, rx: 1 }), h('rect', { x: 15, y: 3, width: 6, height: 6, rx: 1 }), h('rect', { x: 9, y: 15, width: 6, height: 6, rx: 1 }), h('line', { x1: 9, y1: 6, x2: 15, y2: 6 }), h('line', { x1: 12, y1: 9, x2: 12, y2: 15 }), h('line', { x1: 6, y1: 9, x2: 6, y2: 18 }), h('line', { x1: 6, y1: 18, x2: 9, y2: 18 }), h('line', { x1: 18, y1: 9, x2: 18, y2: 18 }), h('line', { x1: 18, y1: 18, x2: 15, y2: 18 })),
46
47
  orgChart: () => h('svg', S, h('rect', { x: 8, y: 2, width: 8, height: 5, rx: 1 }), h('rect', { x: 1, y: 17, width: 8, height: 5, rx: 1 }), h('rect', { x: 15, y: 17, width: 8, height: 5, rx: 1 }), h('line', { x1: 12, y1: 7, x2: 12, y2: 12 }), h('line', { x1: 5, y1: 12, x2: 19, y2: 12 }), h('line', { x1: 5, y1: 12, x2: 5, y2: 17 }), h('line', { x1: 19, y1: 12, x2: 19, y2: 17 })),
47
48
  terminal: () => h('svg', S, h('polyline', { points: '4 17 10 11 4 5' }), h('line', { x1: 12, y1: 19, x2: 20, y2: 19 })),
48
49
  chart: () => h('svg', S, h('line', { x1: 18, y1: 20, x2: 18, y2: 10 }), h('line', { x1: 12, y1: 20, x2: 12, y2: 4 }), h('line', { x1: 6, y1: 20, x2: 6, y2: 14 })),
@@ -1,5 +1,6 @@
1
1
  import { h, useState, useEffect, useCallback, Fragment, engineCall, buildAgentDataMap, renderAgentBadge, getOrgId } from '../components/utils.js';
2
2
  import { DetailModal } from '../components/modal.js';
3
+ import { HelpButton } from '../components/help-button.js';
3
4
 
4
5
  const PAGE_SIZE = 25;
5
6
 
@@ -85,9 +86,21 @@ export function ActivityPage() {
85
86
  const eventsPages = Math.ceil(eventsTotal / PAGE_SIZE);
86
87
  const toolsPages = Math.ceil(toolsTotal / PAGE_SIZE);
87
88
 
89
+ var _h4 = { marginTop: 16, marginBottom: 8, fontSize: 14 };
90
+ var _ul = { paddingLeft: 20, margin: '4px 0 8px' };
91
+ var _tip = { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 };
92
+
88
93
  return h(Fragment, null,
89
94
  h('div', { style: { marginBottom: 20 } },
90
- h('h1', { style: { fontSize: 20, fontWeight: 700 } }, 'Activity'),
95
+ h('h1', { style: { fontSize: 20, fontWeight: 700, display: 'flex', alignItems: 'center' } }, 'Activity', h(HelpButton, { label: 'Activity' },
96
+ h('p', null, 'A real-time feed of everything your agents are doing — events they generate and tools they call.'),
97
+ h('h4', { style: _h4 }, 'Two views'),
98
+ h('ul', { style: _ul },
99
+ h('li', null, h('strong', null, 'Events'), ' — High-level actions: agent started, stopped, deployed, errored, etc.'),
100
+ h('li', null, h('strong', null, 'Tool Calls'), ' — Granular tool usage: which tool, duration, success/failure, parameters and results.')
101
+ ),
102
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Use the agent and type filters to zero in on specific behavior. Click any row to see full details.')
103
+ )),
91
104
  h('p', { style: { color: 'var(--text-muted)', fontSize: 13 } }, 'Real-time activity and tool usage across all agents')
92
105
  ),
93
106
 
@@ -1,6 +1,7 @@
1
1
  import { h, useState, useEffect, useCallback, Fragment, useApp, apiCall, engineCall, formatUptime, buildAgentDataMap, renderAgentBadge, showConfirm, getOrgId } from '../../components/utils.js';
2
2
  import { I } from '../../components/icons.js';
3
3
  import { DetailModal } from '../../components/modal.js';
4
+ import { HelpButton } from '../../components/help-button.js';
4
5
 
5
6
  // --- ActivitySection ------------------------------------------------
6
7
 
@@ -136,7 +137,22 @@ export function ActivitySection(props) {
136
137
 
137
138
  return h('div', { className: 'card' },
138
139
  h('div', { className: 'card-header', style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between' } },
139
- h('h3', { style: { margin: 0, fontSize: 15, fontWeight: 600 } }, 'Activity'),
140
+ h('h3', { style: { margin: 0, fontSize: 15, fontWeight: 600, display: 'flex', alignItems: 'center' } }, 'Activity',
141
+ h(HelpButton, { label: 'Agent Activity Log' },
142
+ h('p', null, 'A chronological log of everything this agent has done — conversations, tasks completed, emails sent, tools used, errors encountered, and guardrail interventions.'),
143
+ h('h4', { style: { marginTop: 16, marginBottom: 8, fontSize: 14 } }, 'Event Types'),
144
+ h('ul', { style: { paddingLeft: 20, margin: '4px 0 8px' } },
145
+ h('li', null, h('strong', null, 'Message'), ' — Chat messages sent or received.'),
146
+ h('li', null, h('strong', null, 'Task'), ' — Tasks started, completed, or failed.'),
147
+ h('li', null, h('strong', null, 'Tool Use'), ' — External tools or APIs the agent called.'),
148
+ h('li', null, h('strong', null, 'Error'), ' — Failures, timeouts, or API errors.'),
149
+ h('li', null, h('strong', null, 'Guardrail'), ' — Policy violations or interventions.'),
150
+ h('li', null, h('strong', null, 'System'), ' — Deploy, restart, config changes.')
151
+ ),
152
+ h('p', null, 'Click on any event to see full details including request/response data.'),
153
+ h('div', { style: { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 } }, h('strong', null, 'Tip: '), 'Use filters to narrow down to specific event types. If debugging an issue, start with "Error" events.')
154
+ )
155
+ ),
140
156
  h('div', { style: { display: 'flex', gap: 8, alignItems: 'center' } },
141
157
  h('span', { style: { fontSize: 11, color: 'var(--text-muted)' } }, filtered.length + ' items'),
142
158
  h('button', { className: 'btn btn-ghost btn-sm', onClick: refreshCurrent }, I.refresh())
@@ -2,6 +2,7 @@ import { h, useState, useEffect, useCallback, Fragment, useApp, apiCall, engineC
2
2
  import { I } from '../../components/icons.js';
3
3
  import { E } from '../../assets/icons/emoji-icons.js';
4
4
  import { Badge, EmptyState } from './shared.js?v=4';
5
+ import { HelpButton } from '../../components/help-button.js';
5
6
 
6
7
  // ════════════════════════════════════════════════════════════
7
8
  // AGENT DETAIL PAGE (Main Orchestrator)
@@ -118,7 +119,22 @@ export function AutonomySection(props) {
118
119
  // Header
119
120
  h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 } },
120
121
  h('div', null,
121
- h('div', { style: { fontSize: 15, fontWeight: 600 } }, 'Agent Autonomy Settings'),
122
+ h('div', { style: { fontSize: 15, fontWeight: 600, display: 'flex', alignItems: 'center' } }, 'Agent Autonomy Settings',
123
+ h(HelpButton, { label: 'Autonomy Settings' },
124
+ h('p', null, 'Autonomy settings control what the agent does automatically without being asked. Think of it as the agent\'s daily routine.'),
125
+ h('h4', { style: { marginTop: 16, marginBottom: 8, fontSize: 14 } }, 'Automated Behaviors'),
126
+ h('ul', { style: { paddingLeft: 20, margin: '4px 0 8px' } },
127
+ h('li', null, h('strong', null, 'Auto Clock-In/Out'), ' — Agent automatically starts and stops work based on its schedule in the Workforce tab.'),
128
+ h('li', null, h('strong', null, 'Daily Catch-up'), ' — At a set time each day, the agent reviews unread emails, messages, and pending tasks to stay on top of things.'),
129
+ h('li', null, h('strong', null, 'Weekly Catch-up'), ' — A deeper weekly review that may include summaries, reports, or planning.'),
130
+ h('li', null, h('strong', null, 'Goal Check'), ' — Periodic check-ins against assigned goals/OKRs.'),
131
+ h('li', null, h('strong', null, 'Knowledge Contributions'), ' — Agent periodically contributes learnings to the organization\'s knowledge base.'),
132
+ h('li', null, h('strong', null, 'Escalation'), ' — Automatically escalates issues it can\'t handle to its manager.'),
133
+ h('li', null, h('strong', null, 'Guardrail Enforcement'), ' — Self-monitors for compliance with organizational policies.')
134
+ ),
135
+ h('div', { style: { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 } }, h('strong', null, 'Tip: '), 'Start with daily catch-up enabled and add more behaviors as the agent proves reliable. The master switch lets you disable all autonomy instantly.')
136
+ )
137
+ ),
122
138
  h('div', { style: { fontSize: 12, color: 'var(--text-muted)' } }, 'Configure automated behaviors — all times use agent timezone')
123
139
  ),
124
140
  h('div', { style: { display: 'flex', gap: 8 } },
@@ -1,6 +1,7 @@
1
1
  import { h, useState, useEffect, useCallback, Fragment, useApp, apiCall, engineCall, formatUptime, buildAgentDataMap, renderAgentBadge, showConfirm, getOrgId } from '../../components/utils.js';
2
2
  import { I } from '../../components/icons.js';
3
3
  import { StatCard, ProgressBar, formatNumber, formatCost } from './shared.js?v=4';
4
+ import { HelpButton } from '../../components/help-button.js';
4
5
 
5
6
  // ════════════════════════════════════════════════════════════
6
7
  // BUDGET SECTION
@@ -117,7 +118,19 @@ export function BudgetSection(props) {
117
118
  // ─── Budget Limits Card ─────────────────────────────
118
119
  h('div', { className: 'card', style: { marginBottom: 20 } },
119
120
  h('div', { className: 'card-header', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } },
120
- h('span', null, 'Budget Limits'),
121
+ h('span', { style: { display: 'flex', alignItems: 'center' } }, 'Budget Limits',
122
+ h(HelpButton, { label: 'Budget Limits' },
123
+ h('p', null, 'Set spending caps to prevent this agent from exceeding your API budget. When a limit is reached, the agent is automatically paused.'),
124
+ h('h4', { style: { marginTop: 16, marginBottom: 8, fontSize: 14 } }, 'Limit Types'),
125
+ h('ul', { style: { paddingLeft: 20, margin: '4px 0 8px' } },
126
+ h('li', null, h('strong', null, 'Daily Limit'), ' — Maximum spend per day (resets at midnight UTC). Prevents runaway costs from a single day\'s usage.'),
127
+ h('li', null, h('strong', null, 'Monthly Limit'), ' — Maximum spend per calendar month. Your overall budget control.'),
128
+ h('li', null, h('strong', null, 'Per-Request Limit'), ' — Maximum cost for a single API call. Prevents accidentally using expensive models or very long prompts.')
129
+ ),
130
+ h('p', null, 'Set to 0 or leave blank for no limit. The progress bars show current usage against each limit.'),
131
+ h('div', { style: { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 } }, h('strong', null, 'Tip: '), 'Start with a conservative daily limit, monitor usage for a week, then adjust. It\'s easier to raise limits than to deal with a surprise $500 bill.')
132
+ )
133
+ ),
121
134
  !editing && h('button', { className: 'btn btn-secondary btn-sm', onClick: function() { setEditing(true); } }, 'Edit Budget')
122
135
  ),
123
136
  h('div', { className: 'card-body' },
@@ -177,7 +190,17 @@ export function BudgetSection(props) {
177
190
 
178
191
  // ─── Budget Alerts Table ────────────────────────────
179
192
  h('div', { className: 'card', style: { marginBottom: 20 } },
180
- h('div', { className: 'card-header' }, h('span', null, 'Budget Alerts')),
193
+ h('div', { className: 'card-header' }, h('span', { style: { display: 'flex', alignItems: 'center' } }, 'Budget Alerts',
194
+ h(HelpButton, { label: 'Budget Alerts' },
195
+ h('p', null, 'Get notified when the agent approaches or exceeds budget thresholds.'),
196
+ h('ul', { style: { paddingLeft: 20, margin: '4px 0 8px' } },
197
+ h('li', null, h('strong', null, 'Warning'), ' — Sent when usage reaches a percentage of the limit (e.g., 80%). Agent continues running.'),
198
+ h('li', null, h('strong', null, 'Critical'), ' — Sent when usage is very close to the limit (e.g., 95%). Consider pausing non-essential tasks.'),
199
+ h('li', null, h('strong', null, 'Exceeded'), ' — The limit was hit and the agent was automatically paused. Requires manual resume or limit increase.')
200
+ ),
201
+ h('div', { style: { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 } }, h('strong', null, 'Tip: '), 'Alerts are sent to the agent\'s manager (if configured) and to the admin email.')
202
+ )
203
+ )),
181
204
  budgetAlerts.length > 0
182
205
  ? h('div', { className: 'card-body-flush' },
183
206
  h('table', { className: 'data-table' },
@@ -1,6 +1,7 @@
1
1
  import { h, useState, useEffect, useCallback, Fragment, useApp, apiCall, engineCall, getOrgId } 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
  // ─── Styles ───
6
7
 
@@ -449,7 +450,15 @@ export function ChannelsSection(props) {
449
450
  var noChannels = !caps?.whatsapp && !caps?.telegram;
450
451
 
451
452
  return h('div', null,
452
- h('h2', { style: { fontSize: '20px', marginBottom: '16px' } }, 'Manager Messaging Channels'),
453
+ h('h2', { style: { fontSize: '20px', marginBottom: '16px', display: 'flex', alignItems: 'center' } }, 'Manager Messaging Channels', h(HelpButton, { label: 'Manager Messaging Channels' },
454
+ h('p', null, 'Connect personal messaging platforms so you can chat with your AI agent directly from WhatsApp or Telegram. These are your private channels — for customer-facing messaging, use the WhatsApp Business tab.'),
455
+ h('ul', { style: { paddingLeft: 20, margin: '4px 0 8px' } },
456
+ h('li', null, h('strong', null, 'Manager Identity'), ' — Set your phone number/user ID so the agent recognizes you across platforms.'),
457
+ h('li', null, h('strong', null, 'WhatsApp'), ' — Link via QR code. Uses your personal WhatsApp as a linked device.'),
458
+ h('li', null, h('strong', null, 'Telegram'), ' — Create a bot via @BotFather and paste the token.')
459
+ ),
460
+ h('div', { style: { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 } }, h('strong', null, 'Tip: '), 'Add trusted contacts to control who can message the agent. Only trusted contacts get responses — everyone else gets an auto-reply.')
461
+ )),
453
462
 
454
463
  noChannels && h('div', { style: Object.assign({}, cardStyle, { textAlign: 'center', padding: '40px' }) },
455
464
  h('div', { style: { marginBottom: '12px' } }, E.chat(40)),
@@ -2,6 +2,7 @@ import { h, useState, useEffect, useCallback, Fragment, useApp, apiCall, engineC
2
2
  import { I } from '../../components/icons.js';
3
3
  import { E } from '../../assets/icons/emoji-icons.js';
4
4
  import { Badge, EmptyState } from './shared.js?v=4';
5
+ import { HelpButton } from '../../components/help-button.js';
5
6
 
6
7
  // --- CommunicationSection -------------------------------------------
7
8
 
@@ -126,7 +127,15 @@ export function CommunicationSection(props) {
126
127
 
127
128
  return h('div', { className: 'card' },
128
129
  h('div', { className: 'card-header', style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between' } },
129
- h('h3', { style: { margin: 0, fontSize: 15, fontWeight: 600 } }, 'Communication'),
130
+ h('h3', { style: { margin: 0, fontSize: 15, fontWeight: 600, display: 'flex', alignItems: 'center' } }, 'Communication', h(HelpButton, { label: 'Communication' },
131
+ h('p', null, 'Inter-agent messaging system. Agents can send messages to each other for coordination, task delegation, and information sharing.'),
132
+ h('ul', { style: { paddingLeft: 20, margin: '4px 0 8px' } },
133
+ h('li', null, h('strong', null, 'All Messages'), ' — Complete message history (sent and received).'),
134
+ h('li', null, h('strong', null, 'Inbox'), ' — Unread messages waiting for this agent. Mark as read after review.'),
135
+ h('li', null, h('strong', null, 'Topology'), ' — Visual map of which agents communicate with each other and how frequently.')
136
+ ),
137
+ h('div', { style: { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 } }, h('strong', null, 'Tip: '), 'Use priority levels (urgent, high, normal, low) to help agents triage incoming messages.')
138
+ )),
130
139
  h('div', { style: { display: 'flex', gap: 8 } },
131
140
  h('button', { className: 'btn btn-primary btn-sm', onClick: function() { setShowSend(true); } }, I.plus(), ' Send Message'),
132
141
  h('button', { className: 'btn btn-ghost btn-sm', onClick: refreshCurrent }, I.refresh(), ' Refresh')
@@ -1,6 +1,12 @@
1
1
  import { h, useState, useEffect, useCallback, Fragment, useApp, apiCall, engineCall, formatUptime, buildAgentDataMap, renderAgentBadge, showConfirm, getOrgId } 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';
5
+
6
+ // ─── Help tooltip styles ───
7
+ var _h4 = { marginTop: 16, marginBottom: 8, fontSize: 14 };
8
+ var _ul = { paddingLeft: 20, margin: '4px 0 8px' };
9
+ var _tip = { marginTop: 12, padding: 12, background: 'var(--bg-secondary, #1e293b)', borderRadius: 'var(--radius, 8px)', fontSize: 13 };
4
10
 
5
11
  // ─── Voice Voices ───
6
12
 
@@ -38,7 +44,7 @@ var rowStyle = { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 };
38
44
 
39
45
  function CardHeader(props) {
40
46
  return h('div', { style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 } },
41
- h('h4', { style: { margin: 0, fontSize: 14, fontWeight: 600 } }, props.title),
47
+ h('h4', { style: { margin: 0, fontSize: 14, fontWeight: 600, display: 'flex', alignItems: 'center' } }, props.title, props.help || null),
42
48
  props.onEdit && !props.editing
43
49
  ? h('button', { className: 'btn btn-ghost btn-sm', onClick: props.onEdit }, 'Edit')
44
50
  : props.editing
@@ -270,6 +276,16 @@ export function ConfigurationSection(props) {
270
276
  h('div', { className: 'card', style: { padding: 20, marginBottom: 20 } },
271
277
  h(CardHeader, {
272
278
  title: 'Default LLM Model',
279
+ help: h(HelpButton, { label: 'Default LLM Model' },
280
+ h('p', null, 'The primary AI model this agent uses for all conversations and tasks.'),
281
+ h('h4', { style: _h4 }, 'Settings'),
282
+ h('ul', { style: _ul },
283
+ h('li', null, h('strong', null, 'Provider'), ' — The AI provider (Anthropic, OpenAI, Google, etc.). Must have an API key configured in Settings > API Keys.'),
284
+ h('li', null, h('strong', null, 'Model'), ' — The specific model to use (e.g., claude-sonnet-4-20250514, gpt-4o). Newer models are generally smarter but cost more.'),
285
+ h('li', null, h('strong', null, 'Thinking Level'), ' — Extended reasoning capability. Higher levels let the model "think step by step" before responding, improving quality for complex tasks at the cost of more tokens.')
286
+ ),
287
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Use Model Routing below to assign different models for different task types — e.g., a cheaper model for chat and a smarter one for complex tasks.')
288
+ ),
273
289
  editing: editingModel,
274
290
  saving: saving,
275
291
  onEdit: function() {
@@ -323,6 +339,19 @@ export function ConfigurationSection(props) {
323
339
  h('div', { className: 'card', style: { padding: 20, marginBottom: 20 } },
324
340
  h(CardHeader, {
325
341
  title: 'Model Routing',
342
+ help: h(HelpButton, { label: 'Model Routing' },
343
+ h('p', null, 'Assign different AI models to different types of tasks. This lets you optimize for cost and quality.'),
344
+ h('h4', { style: _h4 }, 'Task Types'),
345
+ h('ul', { style: _ul },
346
+ h('li', null, h('strong', null, 'Chat'), ' — Real-time conversations (Slack, Teams, WhatsApp). Usually benefits from a fast model.'),
347
+ h('li', null, h('strong', null, 'Meeting'), ' — Meeting summaries and follow-ups. Often needs a larger context window.'),
348
+ h('li', null, h('strong', null, 'Email'), ' — Composing and replying to emails. Benefits from a capable writing model.'),
349
+ h('li', null, h('strong', null, 'Task'), ' — Delegated tasks from managers or other agents.'),
350
+ h('li', null, h('strong', null, 'Scheduling'), ' — Calendar management and scheduling tasks.')
351
+ ),
352
+ h('p', null, 'Leave a route empty to use the Default LLM Model for that task type.'),
353
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Use cheaper models (e.g., claude-haiku, gpt-4o-mini) for simple chat and expensive ones (claude-opus, gpt-4o) for complex tasks to save costs.')
354
+ ),
326
355
  editing: editingRouting,
327
356
  saving: saving,
328
357
  onEdit: function() {
@@ -397,6 +426,14 @@ export function ConfigurationSection(props) {
397
426
  h('div', { className: 'card', style: { padding: 20, marginBottom: 20 } },
398
427
  h(CardHeader, {
399
428
  title: 'Meeting Voice (ElevenLabs)',
429
+ help: h(HelpButton, { label: 'Meeting Voice' },
430
+ h('p', null, 'Configure a text-to-speech voice for this agent to use in meetings and voice interactions via ElevenLabs.'),
431
+ h('ul', { style: _ul },
432
+ h('li', null, 'The voice ID comes from your ElevenLabs dashboard (elevenlabs.io > Voices > Copy Voice ID).'),
433
+ h('li', null, 'Name is just a label for your reference.')
434
+ ),
435
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'ElevenLabs offers free tier voices. Clone a custom voice for your agent\'s unique identity.')
436
+ ),
400
437
  editing: editingVoice,
401
438
  saving: saving,
402
439
  onEdit: function() {
@@ -432,6 +469,10 @@ export function ConfigurationSection(props) {
432
469
  h('div', { className: 'card', style: { padding: 20, marginBottom: 20 } },
433
470
  h(CardHeader, {
434
471
  title: 'Description',
472
+ help: h(HelpButton, { label: 'Agent Description' },
473
+ h('p', null, 'A human-readable description of what this agent does. This is shown to other agents and team members, and is included in the agent\'s system prompt to help it understand its role.'),
474
+ h('div', { style: _tip }, h('strong', null, 'Tip: '), 'Be specific about the agent\'s responsibilities. "Handles customer support for billing questions" is better than "support agent".')
475
+ ),
435
476
  editing: editingDesc,
436
477
  saving: saving,
437
478
  onEdit: function() {