@agenticmail/enterprise 0.5.82 → 0.5.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -48,7 +48,7 @@ Skill Development:
48
48
  break;
49
49
  case "setup":
50
50
  default:
51
- import("./setup-OBJMVWSP.js").then((m) => m.runSetupWizard()).catch(fatal);
51
+ import("./setup-NKJBKCEG.js").then((m) => m.runSetupWizard()).catch(fatal);
52
52
  break;
53
53
  }
54
54
  function fatal(err) {
@@ -3988,6 +3988,190 @@ function ToolsSection(props) {
3988
3988
  // BROWSER CONFIG CARD — Configurable browser settings per agent
3989
3989
  // ════════════════════════════════════════════════════════════
3990
3990
 
3991
+ // ════════════════════════════════════════════════════════════
3992
+ // MEETING CAPABILITIES — Simple toggle, everything auto-managed
3993
+ // ════════════════════════════════════════════════════════════
3994
+
3995
+ function MeetingCapabilitiesSection(props) {
3996
+ var agentId = props.agentId;
3997
+ var cfg = props.cfg;
3998
+ var update = props.update;
3999
+ var sectionStyle = props.sectionStyle;
4000
+ var sectionTitle = props.sectionTitle;
4001
+ var labelStyle = props.labelStyle;
4002
+ var helpStyle = props.helpStyle;
4003
+ var _d = useApp(); var toast = _d.toast;
4004
+ var _launching = useState(false); var launching = _launching[0]; var setLaunching = _launching[1];
4005
+ var _browserStatus = useState(null); var browserStatus = _browserStatus[0]; var setBrowserStatus = _browserStatus[1];
4006
+
4007
+ function checkMeetingBrowser() {
4008
+ engineCall('/bridge/agents/' + agentId + '/browser-config/test', { method: 'POST' })
4009
+ .then(function(d) { setBrowserStatus(d); })
4010
+ .catch(function() { setBrowserStatus(null); });
4011
+ }
4012
+
4013
+ useEffect(function() {
4014
+ if (cfg.meetingsEnabled) checkMeetingBrowser();
4015
+ }, [cfg.meetingsEnabled]);
4016
+
4017
+ function launchMeetingBrowser() {
4018
+ setLaunching(true);
4019
+ engineCall('/bridge/agents/' + agentId + '/browser-config/launch-meeting-browser', { method: 'POST' })
4020
+ .then(function(d) {
4021
+ if (d.error) { toast(d.error, 'error'); }
4022
+ else { toast('Meeting browser ready', 'success'); setBrowserStatus(d); }
4023
+ setLaunching(false);
4024
+ })
4025
+ .catch(function(e) { toast(e.message, 'error'); setLaunching(false); });
4026
+ }
4027
+
4028
+ var meetingsOn = cfg.meetingsEnabled === true;
4029
+
4030
+ return h('div', { style: sectionStyle },
4031
+ sectionTitle('\uD83C\uDFA5', 'Meetings & Video Calls'),
4032
+
4033
+ // Main toggle
4034
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: 16, marginBottom: meetingsOn ? 16 : 0 } },
4035
+ h('div', {
4036
+ onClick: function() { update('meetingsEnabled', !meetingsOn); },
4037
+ style: {
4038
+ width: 52, height: 28, borderRadius: 14, position: 'relative', cursor: 'pointer',
4039
+ background: meetingsOn ? 'var(--accent)' : 'var(--border)', transition: 'background 0.2s', flexShrink: 0,
4040
+ },
4041
+ },
4042
+ h('div', { style: {
4043
+ width: 24, height: 24, borderRadius: 12, background: '#fff', position: 'absolute', top: 2,
4044
+ left: meetingsOn ? 26 : 2, transition: 'left 0.2s',
4045
+ boxShadow: '0 1px 3px rgba(0,0,0,0.2)',
4046
+ } })
4047
+ ),
4048
+ h('div', null,
4049
+ h('div', { style: { fontWeight: 600, fontSize: 13 } }, meetingsOn ? 'Meeting participation enabled' : 'Meeting participation disabled'),
4050
+ h('div', { style: { fontSize: 12, color: 'var(--text-muted)', marginTop: 2 } },
4051
+ meetingsOn
4052
+ ? 'Agent can join Google Meet, Microsoft Teams, and Zoom calls automatically'
4053
+ : 'Enable to let this agent join video calls and meetings on behalf of your organization'
4054
+ )
4055
+ )
4056
+ ),
4057
+
4058
+ // When enabled, show status + options
4059
+ meetingsOn && h('div', null,
4060
+
4061
+ // Status card
4062
+ h('div', { style: { display: 'flex', gap: 12, marginBottom: 16 } },
4063
+ h('div', { className: 'card', style: { flex: 1, padding: '12px 16px' } },
4064
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 } },
4065
+ h('div', { style: {
4066
+ width: 8, height: 8, borderRadius: 4,
4067
+ background: browserStatus?.ok ? 'var(--success)' : 'var(--warning)',
4068
+ } }),
4069
+ h('span', { style: { fontSize: 13, fontWeight: 600 } }, 'Meeting Browser'),
4070
+ browserStatus?.ok && h('span', { className: 'badge', style: { fontSize: 10, padding: '1px 6px', background: 'var(--success-soft)', color: 'var(--success)' } }, 'Running')
4071
+ ),
4072
+ browserStatus?.ok
4073
+ ? h('div', { style: { fontSize: 12, color: 'var(--text-muted)' } }, browserStatus.browserVersion || 'Chromium ready')
4074
+ : h('div', null,
4075
+ h('div', { style: { fontSize: 12, color: 'var(--text-muted)', marginBottom: 8 } }, 'A dedicated browser instance will be launched for video calls with virtual display and audio.'),
4076
+ h('button', { className: 'btn btn-sm', disabled: launching, onClick: launchMeetingBrowser },
4077
+ launching ? 'Launching...' : '\u25B6\uFE0F Launch Meeting Browser'
4078
+ )
4079
+ )
4080
+ )
4081
+ ),
4082
+
4083
+ // Supported platforms
4084
+ h('div', { style: { display: 'grid', gap: 8, gridTemplateColumns: '1fr 1fr 1fr', marginBottom: 16 } },
4085
+ [
4086
+ { name: 'Google Meet', icon: '\uD83D\uDFE2', enabled: cfg.meetingGoogleMeet !== false, key: 'meetingGoogleMeet', desc: 'Join via Google Calendar integration' },
4087
+ { name: 'Microsoft Teams', icon: '\uD83D\uDFE3', enabled: cfg.meetingTeams !== false, key: 'meetingTeams', desc: 'Join via meeting links' },
4088
+ { name: 'Zoom', icon: '\uD83D\uDD35', enabled: cfg.meetingZoom !== false, key: 'meetingZoom', desc: 'Join via meeting links' },
4089
+ ].map(function(p) {
4090
+ return h('div', { key: p.key, className: 'card', style: { padding: '10px 12px', cursor: 'pointer', border: '1px solid ' + (p.enabled ? 'var(--accent)' : 'var(--border)') },
4091
+ onClick: function() { update(p.key, !p.enabled); }
4092
+ },
4093
+ h('div', { style: { display: 'flex', alignItems: 'center', gap: 6, marginBottom: 4 } },
4094
+ h('span', null, p.icon),
4095
+ h('span', { style: { fontWeight: 600, fontSize: 12 } }, p.name),
4096
+ h('span', { style: { marginLeft: 'auto', fontSize: 11, color: p.enabled ? 'var(--success)' : 'var(--text-muted)' } }, p.enabled ? 'ON' : 'OFF')
4097
+ ),
4098
+ h('div', { style: { fontSize: 11, color: 'var(--text-muted)' } }, p.desc)
4099
+ );
4100
+ })
4101
+ ),
4102
+
4103
+ // Meeting behavior
4104
+ h('div', { style: { display: 'grid', gap: 12, gridTemplateColumns: '1fr 1fr' } },
4105
+ h('div', { className: 'form-group' },
4106
+ h('label', { style: labelStyle }, 'Auto-Join Calendar Meetings'),
4107
+ h('select', { className: 'input', value: cfg.meetingAutoJoin || 'ask',
4108
+ onChange: function(e) { update('meetingAutoJoin', e.target.value); }
4109
+ },
4110
+ h('option', { value: 'always' }, 'Always — Join all meetings automatically'),
4111
+ h('option', { value: 'invited' }, 'When Invited — Only join meetings the agent is invited to'),
4112
+ h('option', { value: 'ask' }, 'Ask First — Request approval before joining'),
4113
+ h('option', { value: 'never' }, 'Manual Only — Agent only joins when explicitly told')
4114
+ ),
4115
+ h('div', { style: helpStyle }, 'How the agent decides when to join meetings.')
4116
+ ),
4117
+ h('div', { className: 'form-group' },
4118
+ h('label', { style: labelStyle }, 'Meeting Role'),
4119
+ h('select', { className: 'input', value: cfg.meetingRole || 'observer',
4120
+ onChange: function(e) { update('meetingRole', e.target.value); }
4121
+ },
4122
+ h('option', { value: 'observer' }, 'Observer — Listen and take notes only'),
4123
+ h('option', { value: 'participant' }, 'Participant — Can speak and interact'),
4124
+ h('option', { value: 'presenter' }, 'Presenter — Can share screen and present')
4125
+ ),
4126
+ h('div', { style: helpStyle }, 'What the agent is allowed to do in meetings.')
4127
+ ),
4128
+ h('div', { className: 'form-group' },
4129
+ h('label', { style: labelStyle }, 'Join Timing'),
4130
+ h('select', { className: 'input', value: cfg.meetingJoinTiming || 'ontime',
4131
+ onChange: function(e) { update('meetingJoinTiming', e.target.value); }
4132
+ },
4133
+ h('option', { value: 'early' }, 'Early — Join 2 minutes before start'),
4134
+ h('option', { value: 'ontime' }, 'On Time — Join at scheduled start'),
4135
+ h('option', { value: 'late' }, 'Fashionably Late — Join 2 minutes after start')
4136
+ )
4137
+ ),
4138
+ h('div', { className: 'form-group' },
4139
+ h('label', { style: labelStyle }, 'After Meeting'),
4140
+ h('select', { className: 'input', value: cfg.meetingAfterAction || 'notes',
4141
+ onChange: function(e) { update('meetingAfterAction', e.target.value); }
4142
+ },
4143
+ h('option', { value: 'notes' }, 'Send meeting notes to organizer'),
4144
+ h('option', { value: 'summary' }, 'Post summary to team channel'),
4145
+ h('option', { value: 'transcript' }, 'Save full transcript'),
4146
+ h('option', { value: 'nothing' }, 'Do nothing')
4147
+ ),
4148
+ h('div', { style: helpStyle }, 'What happens after the meeting ends.')
4149
+ )
4150
+ ),
4151
+
4152
+ // Display name in meetings
4153
+ h('div', { style: { display: 'grid', gap: 12, gridTemplateColumns: '1fr 1fr', marginTop: 12 } },
4154
+ h('div', { className: 'form-group' },
4155
+ h('label', { style: labelStyle }, 'Display Name in Meetings'),
4156
+ h('input', { className: 'input', placeholder: 'Agent name (e.g. "Fola - AI Assistant")',
4157
+ value: cfg.meetingDisplayName || '',
4158
+ onChange: function(e) { update('meetingDisplayName', e.target.value || undefined); }
4159
+ }),
4160
+ h('div', { style: helpStyle }, 'How the agent appears to other participants.')
4161
+ ),
4162
+ h('div', { className: 'form-group' },
4163
+ h('label', { style: labelStyle }, 'Max Meeting Duration (minutes)'),
4164
+ h('input', { className: 'input', type: 'number', min: 5, max: 480,
4165
+ value: cfg.meetingMaxDuration || 120,
4166
+ onChange: function(e) { update('meetingMaxDuration', parseInt(e.target.value) || 120); }
4167
+ }),
4168
+ h('div', { style: helpStyle }, 'Agent will leave after this duration to prevent runaway sessions.')
4169
+ )
4170
+ )
4171
+ )
4172
+ );
4173
+ }
4174
+
3991
4175
  function BrowserConfigCard(props) {
3992
4176
  var agentId = props.agentId;
3993
4177
  var _d = useApp(); var toast = _d.toast;
@@ -4420,57 +4604,7 @@ function BrowserConfigCard(props) {
4420
4604
  ),
4421
4605
 
4422
4606
  // ─── Section 4: Meeting & Video Capabilities ─────
4423
- h('div', { style: sectionStyle },
4424
- sectionTitle('\uD83C\uDFA5', 'Meeting & Video Call Capabilities'),
4425
- h('div', { style: { padding: '10px 14px', background: 'var(--bg-secondary)', borderRadius: 'var(--radius)', marginBottom: 12, fontSize: 12, lineHeight: 1.6 } },
4426
- h('div', { style: { fontWeight: 600, marginBottom: 6 } }, 'For Google Meet, Teams, and Zoom:'),
4427
- h('div', null, '\u2022 Use ', h('strong', null, 'Remote Browser (CDP)'), ' provider pointed at a VM with display + virtual camera'),
4428
- h('div', null, '\u2022 The remote machine needs: X11/Wayland display, PulseAudio/PipeWire (audio), v4l2loopback (virtual camera)'),
4429
- h('div', null, '\u2022 Agent will navigate to meeting URL, handle permissions, and interact with the meeting UI'),
4430
- h('div', null, '\u2022 For voice participation: integrate with a Speech-to-Text / Text-to-Speech service'),
4431
- h('div', { style: { marginTop: 8 } },
4432
- h('strong', null, 'Quick VM Setup (Linux):'),
4433
- h('pre', { style: { margin: '6px 0', padding: 8, background: 'var(--bg-tertiary)', borderRadius: 4, fontSize: 11, overflow: 'auto' } },
4434
- '# Install deps\nsudo apt install -y xvfb pulseaudio chromium v4l2loopback-dkms\n\n# Start virtual display + audio\nXvfb :99 -screen 0 1920x1080x24 &\nexport DISPLAY=:99\npulseaudio --start\n\n# Launch Chrome with remote debugging\nchromium --remote-debugging-port=9222 \\\n --no-first-run --disable-gpu \\\n --use-fake-ui-for-media-stream \\\n --use-fake-device-for-media-stream \\\n --auto-accept-camera-and-microphone-capture'
4435
- )
4436
- )
4437
- ),
4438
- h('div', { style: { display: 'grid', gap: 12, gridTemplateColumns: '1fr 1fr' } },
4439
- h('div', { className: 'form-group' },
4440
- h('label', { style: labelStyle }, 'Auto-Accept Permissions'),
4441
- h('select', { className: 'input', value: cfg.autoAcceptPermissions !== false ? 'true' : 'false',
4442
- onChange: function(e) { update('autoAcceptPermissions', e.target.value === 'true'); }
4443
- },
4444
- h('option', { value: 'true' }, 'Yes — Auto-grant camera/microphone access'),
4445
- h('option', { value: 'false' }, 'No — Require manual permission grants')
4446
- )
4447
- ),
4448
- h('div', { className: 'form-group' },
4449
- h('label', { style: labelStyle }, 'Virtual Camera Feed'),
4450
- h('input', { className: 'input', placeholder: '/dev/video0 or URL to video feed',
4451
- value: cfg.virtualCameraSource || '',
4452
- onChange: function(e) { update('virtualCameraSource', e.target.value || undefined); }
4453
- }),
4454
- h('div', { style: helpStyle }, 'Video source for the agent\'s "camera" in meetings.')
4455
- ),
4456
- h('div', { className: 'form-group' },
4457
- h('label', { style: labelStyle }, 'Audio Input'),
4458
- h('input', { className: 'input', placeholder: 'PulseAudio source (e.g. virtual_mic)',
4459
- value: cfg.audioInput || '',
4460
- onChange: function(e) { update('audioInput', e.target.value || undefined); }
4461
- }),
4462
- h('div', { style: helpStyle }, 'Audio source for the agent to speak in meetings.')
4463
- ),
4464
- h('div', { className: 'form-group' },
4465
- h('label', { style: labelStyle }, 'Audio Output'),
4466
- h('input', { className: 'input', placeholder: 'PulseAudio sink (e.g. virtual_speaker)',
4467
- value: cfg.audioOutput || '',
4468
- onChange: function(e) { update('audioOutput', e.target.value || undefined); }
4469
- }),
4470
- h('div', { style: helpStyle }, 'Audio sink for the agent to hear meeting participants.')
4471
- )
4472
- )
4473
- ),
4607
+ h(MeetingCapabilitiesSection, { agentId: agentId, cfg: cfg, update: update, labelStyle: labelStyle, helpStyle: helpStyle, sectionStyle: sectionStyle, sectionTitle: sectionTitle }),
4474
4608
 
4475
4609
  // ─── Section 5: Persistent Sessions ──────────────
4476
4610
  h('div', { style: { paddingTop: 12 } },
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ import {
35
35
  executeTool,
36
36
  runAgentLoop,
37
37
  toolsToDefinitions
38
- } from "./chunk-HP2BGRVX.js";
38
+ } from "./chunk-4DXQQPEC.js";
39
39
  import "./chunk-TYW5XTOW.js";
40
40
  import {
41
41
  ValidationError,
@@ -50,11 +50,11 @@ import {
50
50
  requireRole,
51
51
  securityHeaders,
52
52
  validate
53
- } from "./chunk-UJFEKPLU.js";
53
+ } from "./chunk-SEGTMIPI.js";
54
54
  import {
55
55
  provision,
56
56
  runSetupWizard
57
- } from "./chunk-CFEPEV5P.js";
57
+ } from "./chunk-ZTOVB5OQ.js";
58
58
  import {
59
59
  ENGINE_TABLES,
60
60
  ENGINE_TABLES_POSTGRES,