@agenticmail/enterprise 0.5.281 → 0.5.283

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 (39) hide show
  1. package/dist/agent-heartbeat-HVKMZXEP.js +510 -0
  2. package/dist/agent-tools-FXT4DWIT.js +7 -0
  3. package/dist/agent-tools-VQ3MX746.js +13881 -0
  4. package/dist/browser-tool-VRCAS76F.js +4003 -0
  5. package/dist/chunk-2FOASCL5.js +4739 -0
  6. package/dist/chunk-5Z4QW7FI.js +1036 -0
  7. package/dist/chunk-KPGXRGQ4.js +4735 -0
  8. package/dist/chunk-KUUIDXRJ.js +3780 -0
  9. package/dist/chunk-LODP4ATE.js +1224 -0
  10. package/dist/chunk-O3RXJSHR.js +3780 -0
  11. package/dist/chunk-P5EGIVSM.js +1224 -0
  12. package/dist/chunk-V3AM4LOU.js +2594 -0
  13. package/dist/chunk-XPOPU7F4.js +177 -0
  14. package/dist/cli-agent-4C36ET7J.js +1778 -0
  15. package/dist/cli-agent-5OF74Z3A.js +1778 -0
  16. package/dist/cli-serve-756HRJOT.js +114 -0
  17. package/dist/cli-serve-TJ4ED5FM.js +114 -0
  18. package/dist/cli.js +3 -3
  19. package/dist/connection-manager-UHQRYZV2.js +7 -0
  20. package/dist/dashboard/pages/database-access.js +63 -14
  21. package/dist/index.js +23 -23
  22. package/dist/meetings-RR72OBSV.js +1 -1
  23. package/dist/routes-YARSSU26.js +13695 -0
  24. package/dist/runtime-3BM2W3YT.js +45 -0
  25. package/dist/runtime-RILCPBIB.js +45 -0
  26. package/dist/server-AICCPX7S.js +15 -0
  27. package/dist/server-XVIBYRNU.js +15 -0
  28. package/dist/setup-DAT4LP7A.js +20 -0
  29. package/dist/setup-I23IJDTG.js +20 -0
  30. package/package.json +1 -1
  31. package/src/agent-tools/index.ts +11 -0
  32. package/src/agent-tools/types.ts +2 -0
  33. package/src/cli-agent.ts +13 -0
  34. package/src/dashboard/pages/database-access.js +63 -14
  35. package/src/database-access/connection-manager.ts +28 -0
  36. package/src/database-access/routes.ts +23 -1
  37. package/src/runtime/index.ts +8 -0
  38. package/src/runtime/types.ts +2 -0
  39. package/src/server.ts +6 -4
@@ -0,0 +1,45 @@
1
+ import {
2
+ AgentRuntime,
3
+ EmailChannel,
4
+ FollowUpScheduler,
5
+ SessionManager,
6
+ SubAgentManager,
7
+ ToolRegistry,
8
+ callLLM,
9
+ createAgentRuntime,
10
+ createNoopHooks,
11
+ createRuntimeHooks,
12
+ estimateMessageTokens,
13
+ estimateTokens,
14
+ executeTool,
15
+ runAgentLoop,
16
+ toolsToDefinitions
17
+ } from "./chunk-2FOASCL5.js";
18
+ import {
19
+ PROVIDER_REGISTRY,
20
+ listAllProviders,
21
+ resolveApiKeyForProvider,
22
+ resolveProvider
23
+ } from "./chunk-UF3ZJMJO.js";
24
+ import "./chunk-KFQGP6VL.js";
25
+ export {
26
+ AgentRuntime,
27
+ EmailChannel,
28
+ FollowUpScheduler,
29
+ PROVIDER_REGISTRY,
30
+ SessionManager,
31
+ SubAgentManager,
32
+ ToolRegistry,
33
+ callLLM,
34
+ createAgentRuntime,
35
+ createNoopHooks,
36
+ createRuntimeHooks,
37
+ estimateMessageTokens,
38
+ estimateTokens,
39
+ executeTool,
40
+ listAllProviders,
41
+ resolveApiKeyForProvider,
42
+ resolveProvider,
43
+ runAgentLoop,
44
+ toolsToDefinitions
45
+ };
@@ -0,0 +1,45 @@
1
+ import {
2
+ AgentRuntime,
3
+ EmailChannel,
4
+ FollowUpScheduler,
5
+ SessionManager,
6
+ SubAgentManager,
7
+ ToolRegistry,
8
+ callLLM,
9
+ createAgentRuntime,
10
+ createNoopHooks,
11
+ createRuntimeHooks,
12
+ estimateMessageTokens,
13
+ estimateTokens,
14
+ executeTool,
15
+ runAgentLoop,
16
+ toolsToDefinitions
17
+ } from "./chunk-KPGXRGQ4.js";
18
+ import {
19
+ PROVIDER_REGISTRY,
20
+ listAllProviders,
21
+ resolveApiKeyForProvider,
22
+ resolveProvider
23
+ } from "./chunk-UF3ZJMJO.js";
24
+ import "./chunk-KFQGP6VL.js";
25
+ export {
26
+ AgentRuntime,
27
+ EmailChannel,
28
+ FollowUpScheduler,
29
+ PROVIDER_REGISTRY,
30
+ SessionManager,
31
+ SubAgentManager,
32
+ ToolRegistry,
33
+ callLLM,
34
+ createAgentRuntime,
35
+ createNoopHooks,
36
+ createRuntimeHooks,
37
+ estimateMessageTokens,
38
+ estimateTokens,
39
+ executeTool,
40
+ listAllProviders,
41
+ resolveApiKeyForProvider,
42
+ resolveProvider,
43
+ runAgentLoop,
44
+ toolsToDefinitions
45
+ };
@@ -0,0 +1,15 @@
1
+ import {
2
+ createServer
3
+ } from "./chunk-KUUIDXRJ.js";
4
+ import "./chunk-OF4MUWWS.js";
5
+ import "./chunk-UF3ZJMJO.js";
6
+ import "./chunk-3OC6RH7W.js";
7
+ import "./chunk-2DDKGTD6.js";
8
+ import "./chunk-YVK6F5OD.js";
9
+ import "./chunk-MKRNEM5A.js";
10
+ import "./chunk-DRXMYYKN.js";
11
+ import "./chunk-6WSX7QXF.js";
12
+ import "./chunk-KFQGP6VL.js";
13
+ export {
14
+ createServer
15
+ };
@@ -0,0 +1,15 @@
1
+ import {
2
+ createServer
3
+ } from "./chunk-O3RXJSHR.js";
4
+ import "./chunk-OF4MUWWS.js";
5
+ import "./chunk-UF3ZJMJO.js";
6
+ import "./chunk-3OC6RH7W.js";
7
+ import "./chunk-2DDKGTD6.js";
8
+ import "./chunk-YVK6F5OD.js";
9
+ import "./chunk-MKRNEM5A.js";
10
+ import "./chunk-DRXMYYKN.js";
11
+ import "./chunk-6WSX7QXF.js";
12
+ import "./chunk-KFQGP6VL.js";
13
+ export {
14
+ createServer
15
+ };
@@ -0,0 +1,20 @@
1
+ import {
2
+ promptCompanyInfo,
3
+ promptDatabase,
4
+ promptDeployment,
5
+ promptDomain,
6
+ promptRegistration,
7
+ provision,
8
+ runSetupWizard
9
+ } from "./chunk-P5EGIVSM.js";
10
+ import "./chunk-ULRBF2T7.js";
11
+ import "./chunk-KFQGP6VL.js";
12
+ export {
13
+ promptCompanyInfo,
14
+ promptDatabase,
15
+ promptDeployment,
16
+ promptDomain,
17
+ promptRegistration,
18
+ provision,
19
+ runSetupWizard
20
+ };
@@ -0,0 +1,20 @@
1
+ import {
2
+ promptCompanyInfo,
3
+ promptDatabase,
4
+ promptDeployment,
5
+ promptDomain,
6
+ promptRegistration,
7
+ provision,
8
+ runSetupWizard
9
+ } from "./chunk-LODP4ATE.js";
10
+ import "./chunk-ULRBF2T7.js";
11
+ import "./chunk-KFQGP6VL.js";
12
+ export {
13
+ promptCompanyInfo,
14
+ promptDatabase,
15
+ promptDeployment,
16
+ promptDomain,
17
+ promptRegistration,
18
+ provision,
19
+ runSetupWizard
20
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticmail/enterprise",
3
- "version": "0.5.281",
3
+ "version": "0.5.283",
4
4
  "description": "AgenticMail Enterprise — cloud-hosted AI agent identity, email, auth & compliance for organizations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -305,6 +305,17 @@ export async function createAllTools(options?: AllToolsOptions): Promise<AnyAgen
305
305
  var visualMemoryTools = createVisualMemoryTools(options || {});
306
306
  rawTools = rawTools.concat(visualMemoryTools as any);
307
307
 
308
+ // Enterprise Database Access tools (real multi-DB connections via DatabaseConnectionManager)
309
+ if ((options as any)?.databaseManager && options?.agentId) {
310
+ try {
311
+ const { createDatabaseTools: createDbAccessTools } = await import('../database-access/agent-tools.js');
312
+ const dbAccessTools = createDbAccessTools((options as any).databaseManager, options.agentId);
313
+ rawTools = rawTools.concat(dbAccessTools as any);
314
+ } catch (e: any) {
315
+ console.warn('[tools] Failed to load database access tools:', e.message);
316
+ }
317
+ }
318
+
308
319
  // Enterprise tools (7 skills)
309
320
  var enterpriseTools: AnyAgentTool[] = [
310
321
  ...createDatabaseTools(options),
@@ -128,6 +128,8 @@ export interface ToolCreationOptions {
128
128
  };
129
129
  /** Engine database reference for tools that need DB access */
130
130
  engineDb?: any;
131
+ /** Database Connection Manager for enterprise database access */
132
+ databaseManager?: any;
131
133
  /** Middleware configuration for cross-cutting concerns */
132
134
  middleware?: {
133
135
  audit?: {
package/src/cli-agent.ts CHANGED
@@ -586,6 +586,19 @@ export async function runAgent(_args: string[]) {
586
586
  console.warn(`[agent] MCP Process Manager init failed (non-fatal): ${e.message}`);
587
587
  }
588
588
 
589
+ // ─── Database Connection Manager ───────────────────
590
+ // Enables agents to query external databases they've been granted access to
591
+ try {
592
+ const { DatabaseConnectionManager } = await import('./database-access/connection-manager.js');
593
+ const vault = (runtime as any).config?.vault;
594
+ const dbManager = new DatabaseConnectionManager({ vault });
595
+ await dbManager.setDb(engineDb);
596
+ (runtime as any).config.databaseManager = dbManager;
597
+ console.log(`[agent] Database Connection Manager started`);
598
+ } catch (e: any) {
599
+ console.warn(`[agent] Database Connection Manager init failed (non-fatal): ${e.message}`);
600
+ }
601
+
589
602
  await runtime.start();
590
603
  const runtimeApp = runtime.getApp();
591
604
 
@@ -473,26 +473,63 @@ function AddConnectionModal(props) {
473
473
  var [dbType, setDbType] = useState('');
474
474
  var [form, setForm] = useState({ name: '', host: '', port: '', database: '', username: '', password: '', connectionString: '', ssl: false, description: '' });
475
475
  var [saving, setSaving] = useState(false);
476
+ var [testing, setTesting] = useState(false);
477
+ var [testResult, setTestResult] = useState(null); // { success, error, latencyMs }
476
478
 
477
- var set = function(key, val) { setForm(function(f) { var n = Object.assign({}, f); n[key] = val; return n; }); };
479
+ var set = function(key, val) { setForm(function(f) { var n = Object.assign({}, f); n[key] = val; return n; }); setTestResult(null); };
478
480
 
479
481
  var isConnString = form.connectionString.length > 0;
480
482
 
483
+ var buildBody = function() {
484
+ var body = { type: dbType, name: form.name || (ALL_DB_TYPES.find(function(t) { return t.value === dbType; })?.label + ' Connection'), description: form.description, status: 'inactive' };
485
+ if (isConnString) {
486
+ body.connectionString = form.connectionString;
487
+ } else {
488
+ body.host = form.host;
489
+ body.port = form.port ? parseInt(form.port) : undefined;
490
+ body.database = form.database;
491
+ body.username = form.username;
492
+ body.password = form.password;
493
+ body.ssl = form.ssl;
494
+ }
495
+ return body;
496
+ };
497
+
498
+ var testConnection = async function() {
499
+ setTesting(true);
500
+ setTestResult(null);
501
+ try {
502
+ var result = await engineCall('/database/connections/test', { method: 'POST', body: JSON.stringify(buildBody()) });
503
+ setTestResult(result);
504
+ } catch (e) {
505
+ setTestResult({ success: false, error: e.message || 'Connection test failed' });
506
+ }
507
+ setTesting(false);
508
+ };
509
+
481
510
  var save = async function() {
511
+ // Test connection first if not already tested successfully
512
+ if (!testResult || !testResult.success) {
513
+ setTesting(true);
514
+ setTestResult(null);
515
+ try {
516
+ var result = await engineCall('/database/connections/test', { method: 'POST', body: JSON.stringify(buildBody()) });
517
+ setTestResult(result);
518
+ if (!result.success) {
519
+ setTesting(false);
520
+ return; // Don't save if test fails
521
+ }
522
+ } catch (e) {
523
+ setTestResult({ success: false, error: e.message || 'Connection test failed' });
524
+ setTesting(false);
525
+ return;
526
+ }
527
+ setTesting(false);
528
+ }
529
+
482
530
  setSaving(true);
483
531
  try {
484
- var body = { type: dbType, name: form.name || (ALL_DB_TYPES.find(function(t) { return t.value === dbType; })?.label + ' Connection'), description: form.description, status: 'inactive' };
485
- if (isConnString) {
486
- body.connectionString = form.connectionString;
487
- } else {
488
- body.host = form.host;
489
- body.port = form.port ? parseInt(form.port) : undefined;
490
- body.database = form.database;
491
- body.username = form.username;
492
- body.password = form.password;
493
- body.ssl = form.ssl;
494
- }
495
- await engineCall('/database/connections', { method: 'POST', body: JSON.stringify(body) });
532
+ await engineCall('/database/connections', { method: 'POST', body: JSON.stringify(buildBody()) });
496
533
  props.onSave();
497
534
  props.onClose();
498
535
  } catch (e) { alert('Failed: ' + e.message); }
@@ -572,9 +609,21 @@ function AddConnectionModal(props) {
572
609
  h('div', { style: s.label }, 'Description (optional)'),
573
610
  h('input', { style: s.input, placeholder: 'What is this database used for?', value: form.description, onInput: function(e) { set('description', e.target.value); } }),
574
611
  ),
612
+ // Connection test result
613
+ testResult && h('div', { style: css('padding: 8px 12px; border-radius: 6px; font-size: 12px; ' + (testResult.success
614
+ ? 'background: rgba(21,128,61,0.1); color: var(--success); border: 1px solid rgba(21,128,61,0.3);'
615
+ : 'background: rgba(239,68,68,0.1); color: var(--danger); border: 1px solid rgba(239,68,68,0.3);')) },
616
+ testResult.success
617
+ ? 'Connection successful! (' + testResult.latencyMs + 'ms)'
618
+ : 'Connection failed: ' + (testResult.error || 'Unknown error'),
619
+ ),
620
+
575
621
  h('div', { style: css('display: flex; justify-content: space-between; margin-top: 8px;') },
576
622
  h('button', { style: s.btn, onClick: function() { setStep(1); } }, '← Back'),
577
- h('button', { style: s.btnPrimary, disabled: saving || (!isConnString && !form.host), onClick: save }, saving ? 'Saving...' : 'Add Connection'),
623
+ h('div', { style: css('display: flex; gap: 8px;') },
624
+ h('button', { style: s.btn, disabled: testing || saving || (!isConnString && !form.host), onClick: testConnection }, testing ? 'Testing...' : 'Test Connection'),
625
+ h('button', { style: s.btnPrimary, disabled: testing || saving || (!isConnString && !form.host), onClick: save }, saving ? 'Saving...' : testing ? 'Testing...' : 'Add Connection'),
626
+ ),
578
627
  ),
579
628
  ),
580
629
  ),
@@ -534,6 +534,34 @@ export class DatabaseConnectionManager {
534
534
  }
535
535
  }
536
536
 
537
+ /**
538
+ * Test connection parameters without saving — creates a temporary connection,
539
+ * pings it, and immediately destroys it.
540
+ */
541
+ async testConnectionParams(params: {
542
+ type: string; host?: string; port?: number; database?: string;
543
+ username?: string; password?: string; connectionString?: string; ssl?: boolean;
544
+ }): Promise<{ success: boolean; latencyMs: number; error?: string }> {
545
+ const startMs = Date.now();
546
+ const driver = this.drivers.get(params.type as any);
547
+ if (!driver) return { success: false, latencyMs: 0, error: `No driver for database type: ${params.type}` };
548
+
549
+ let connection: any;
550
+ try {
551
+ connection = await driver.connect(
552
+ { type: params.type as any, host: params.host, port: params.port, database: params.database, ssl: params.ssl } as any,
553
+ { password: params.password, connectionString: params.connectionString },
554
+ );
555
+ const alive = await connection.ping();
556
+ const latencyMs = Date.now() - startMs;
557
+ return { success: alive, latencyMs };
558
+ } catch (err: any) {
559
+ return { success: false, latencyMs: Date.now() - startMs, error: err.message };
560
+ } finally {
561
+ try { if (connection?.close) await connection.close(); } catch {}
562
+ }
563
+ }
564
+
537
565
  // ─── Pool Management ───────────────────────────────────────────────────────
538
566
 
539
567
  private async getPooledConnection(connectionId: string): Promise<DatabaseConnection> {
@@ -88,7 +88,29 @@ export function createDatabaseAccessRoutes(manager: DatabaseConnectionManager) {
88
88
  return c.json({ ok: true });
89
89
  });
90
90
 
91
- /** Test a database connection */
91
+ /** Test connection parameters before saving (no persistence) — must come before :id routes */
92
+ router.post('/connections/test', async (c) => {
93
+ const body = await c.req.json();
94
+ if (!body.type) return c.json({ error: 'type is required' }, 400);
95
+ const startMs = Date.now();
96
+ try {
97
+ const result = await manager.testConnectionParams({
98
+ type: body.type,
99
+ host: body.host,
100
+ port: body.port,
101
+ database: body.database,
102
+ username: body.username,
103
+ password: body.password,
104
+ connectionString: body.connectionString,
105
+ ssl: body.ssl,
106
+ });
107
+ return c.json(result);
108
+ } catch (e: any) {
109
+ return c.json({ success: false, latencyMs: Date.now() - startMs, error: e.message || 'Connection test failed' });
110
+ }
111
+ });
112
+
113
+ /** Test an existing database connection */
92
114
  router.post('/connections/:id/test', async (c) => {
93
115
  const result = await manager.testConnection(c.req.param('id'));
94
116
  return c.json(result);
@@ -228,6 +228,10 @@ export class AgentRuntime {
228
228
  if (this.config.mcpProcessManager) {
229
229
  base.mcpProcessManager = this.config.mcpProcessManager;
230
230
  }
231
+ // Database Connection Manager — enterprise database access tools
232
+ if (this.config.databaseManager) {
233
+ base.databaseManager = this.config.databaseManager;
234
+ }
231
235
  return base;
232
236
  }
233
237
 
@@ -1000,6 +1004,10 @@ Guidelines:
1000
1004
  - Before complex tasks, call memory_context to recall relevant knowledge
1001
1005
  - Your memory persists across conversations — it's how you grow as an expert
1002
1006
 
1007
+ Database Tools:
1008
+ - ent_db_* tools (ent_db_query, ent_db_tables, ent_db_schema, ent_db_sample, ent_db_explain): For LOCAL databases — SQLite files in the workspace or registered local connections. Read-only.
1009
+ - db_* tools (db_query, db_list_connections, db_list_tables, db_describe_table): For CLOUD/ENTERPRISE databases — Postgres, MySQL, MongoDB, Redis, Supabase, etc. configured by your admin. Use db_list_connections first to see what databases you have access to. Supports read and write operations based on your granted permissions.
1010
+
1003
1011
  Current time: ${new Date().toISOString()}`;
1004
1012
 
1005
1013
  if (memoryContext) {
@@ -140,6 +140,8 @@ export interface RuntimeConfig {
140
140
  permissionEngine?: any;
141
141
  /** MCP Process Manager for external MCP server tools */
142
142
  mcpProcessManager?: import('../engine/mcp-process-manager.js').McpProcessManager;
143
+ /** Database Connection Manager for enterprise database access tools */
144
+ databaseManager?: import('../database-access/connection-manager.js').DatabaseConnectionManager;
143
145
  /** Knowledge base engine for RAG search tools */
144
146
  knowledgeEngine?: any;
145
147
  /** Real-time agent status tracker */
package/src/server.ts CHANGED
@@ -355,7 +355,7 @@ export function createServer(config: ServerConfig): ServerInstance {
355
355
  };
356
356
  }
357
357
  } catch {}
358
- const { vault: vaultRef, permissionEngine: permRef } = await import('./engine/routes.js');
358
+ const { vault: vaultRef, permissionEngine: permRef, databaseManager: dbMgr } = await import('./engine/routes.js');
359
359
  const runtime = createAgentRuntime({
360
360
  engineDb,
361
361
  adminDb: config.db,
@@ -367,7 +367,8 @@ export function createServer(config: ServerConfig): ServerInstance {
367
367
  agentMemoryManager: agentMemoryMgr,
368
368
  vault: vaultRef,
369
369
  permissionEngine: permRef,
370
- });
370
+ databaseManager: dbMgr,
371
+ } as any);
371
372
  await runtime.start();
372
373
  const runtimeApp = runtime.getApp();
373
374
  if (runtimeApp) {
@@ -620,7 +621,7 @@ export function createServer(config: ServerConfig): ServerInstance {
620
621
  };
621
622
  }
622
623
  } catch {}
623
- const { vault: vaultRef2, permissionEngine: permRef2 } = await import('./engine/routes.js');
624
+ const { vault: vaultRef2, permissionEngine: permRef2, databaseManager: dbMgr2 } = await import('./engine/routes.js');
624
625
  const runtime = createAgentRuntime({
625
626
  engineDb,
626
627
  adminDb: config.db,
@@ -633,7 +634,8 @@ export function createServer(config: ServerConfig): ServerInstance {
633
634
  vault: vaultRef2,
634
635
  permissionEngine: permRef2,
635
636
  hierarchyManager: (await import('./engine/routes.js')).hierarchyManager ?? undefined,
636
- });
637
+ databaseManager: dbMgr2,
638
+ } as any);
637
639
  await runtime.start();
638
640
  const runtimeApp = runtime.getApp();
639
641
  if (runtimeApp) mountRuntimeApp(runtimeApp);