@agenticmail/enterprise 0.5.103 → 0.5.105

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.
@@ -0,0 +1,49 @@
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-SFLOH6XF.js";
18
+ import "./chunk-TYW5XTOW.js";
19
+ import "./chunk-AQH4DFYV.js";
20
+ import {
21
+ PROVIDER_REGISTRY,
22
+ listAllProviders,
23
+ resolveApiKeyForProvider,
24
+ resolveProvider
25
+ } from "./chunk-67KZYSLU.js";
26
+ import "./chunk-JLSQOQ5L.js";
27
+ import "./chunk-NRF3YRF7.js";
28
+ import "./chunk-KFQGP6VL.js";
29
+ export {
30
+ AgentRuntime,
31
+ EmailChannel,
32
+ FollowUpScheduler,
33
+ PROVIDER_REGISTRY,
34
+ SessionManager,
35
+ SubAgentManager,
36
+ ToolRegistry,
37
+ callLLM,
38
+ createAgentRuntime,
39
+ createNoopHooks,
40
+ createRuntimeHooks,
41
+ estimateMessageTokens,
42
+ estimateTokens,
43
+ executeTool,
44
+ listAllProviders,
45
+ resolveApiKeyForProvider,
46
+ resolveProvider,
47
+ runAgentLoop,
48
+ toolsToDefinitions
49
+ };
@@ -0,0 +1,49 @@
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-EVLC3NXM.js";
18
+ import "./chunk-NRF3YRF7.js";
19
+ import "./chunk-TYW5XTOW.js";
20
+ import "./chunk-AQH4DFYV.js";
21
+ import "./chunk-JLSQOQ5L.js";
22
+ import {
23
+ PROVIDER_REGISTRY,
24
+ listAllProviders,
25
+ resolveApiKeyForProvider,
26
+ resolveProvider
27
+ } from "./chunk-67KZYSLU.js";
28
+ import "./chunk-KFQGP6VL.js";
29
+ export {
30
+ AgentRuntime,
31
+ EmailChannel,
32
+ FollowUpScheduler,
33
+ PROVIDER_REGISTRY,
34
+ SessionManager,
35
+ SubAgentManager,
36
+ ToolRegistry,
37
+ callLLM,
38
+ createAgentRuntime,
39
+ createNoopHooks,
40
+ createRuntimeHooks,
41
+ estimateMessageTokens,
42
+ estimateTokens,
43
+ executeTool,
44
+ listAllProviders,
45
+ resolveApiKeyForProvider,
46
+ resolveProvider,
47
+ runAgentLoop,
48
+ toolsToDefinitions
49
+ };
@@ -0,0 +1,12 @@
1
+ import {
2
+ createServer
3
+ } from "./chunk-SNZUZYHO.js";
4
+ import "./chunk-3SMTCIR4.js";
5
+ import "./chunk-JLSQOQ5L.js";
6
+ import "./chunk-RO537U6H.js";
7
+ import "./chunk-DRXMYYKN.js";
8
+ import "./chunk-67KZYSLU.js";
9
+ import "./chunk-KFQGP6VL.js";
10
+ export {
11
+ createServer
12
+ };
@@ -0,0 +1,12 @@
1
+ import {
2
+ createServer
3
+ } from "./chunk-7V7ZZJAG.js";
4
+ import "./chunk-3SMTCIR4.js";
5
+ import "./chunk-RO537U6H.js";
6
+ import "./chunk-DRXMYYKN.js";
7
+ import "./chunk-67KZYSLU.js";
8
+ import "./chunk-JLSQOQ5L.js";
9
+ import "./chunk-KFQGP6VL.js";
10
+ export {
11
+ createServer
12
+ };
@@ -0,0 +1,20 @@
1
+ import {
2
+ promptCompanyInfo,
3
+ promptDatabase,
4
+ promptDeployment,
5
+ promptDomain,
6
+ promptRegistration,
7
+ provision,
8
+ runSetupWizard
9
+ } from "./chunk-ZFO44EVP.js";
10
+ import "./chunk-QDXUZP7Y.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-I7MWMKQX.js";
10
+ import "./chunk-QDXUZP7Y.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.103",
3
+ "version": "0.5.105",
4
4
  "description": "AgenticMail Enterprise — cloud-hosted AI agent identity, email, auth & compliance for organizations",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,201 @@
1
+ /**
2
+ * `npx @agenticmail/enterprise agent`
3
+ *
4
+ * Standalone agent runtime — runs a single agent as its own process.
5
+ * Designed for Fly.io / Docker deployments where each agent gets its own machine.
6
+ *
7
+ * Required env vars:
8
+ * DATABASE_URL — Postgres connection string (shared enterprise DB)
9
+ * JWT_SECRET — JWT signing secret (must match enterprise server)
10
+ * AGENTICMAIL_AGENT_ID — Agent UUID from the enterprise DB
11
+ *
12
+ * Optional env vars:
13
+ * PORT — Health check HTTP port (default: 3000)
14
+ * AGENTICMAIL_MODEL — Override model (e.g. "anthropic/claude-sonnet-4-20250514")
15
+ * AGENTICMAIL_THINKING — Thinking level (e.g. "low", "medium", "high")
16
+ * ANTHROPIC_API_KEY — Anthropic API key
17
+ * OPENAI_API_KEY — OpenAI API key
18
+ * XAI_API_KEY — xAI API key
19
+ */
20
+
21
+ import { Hono } from 'hono';
22
+ import { serve } from '@hono/node-server';
23
+
24
+ export async function runAgent(_args: string[]) {
25
+ const DATABASE_URL = process.env.DATABASE_URL;
26
+ const JWT_SECRET = process.env.JWT_SECRET;
27
+ const AGENT_ID = process.env.AGENTICMAIL_AGENT_ID;
28
+ const PORT = parseInt(process.env.PORT || '3000', 10);
29
+
30
+ if (!DATABASE_URL) { console.error('ERROR: DATABASE_URL is required'); process.exit(1); }
31
+ if (!JWT_SECRET) { console.error('ERROR: JWT_SECRET is required'); process.exit(1); }
32
+ if (!AGENT_ID) { console.error('ERROR: AGENTICMAIL_AGENT_ID is required'); process.exit(1); }
33
+
34
+ console.log('🤖 AgenticMail Agent Runtime');
35
+ console.log(` Agent ID: ${AGENT_ID}`);
36
+ console.log(' Connecting to database...');
37
+
38
+ // 1. Connect to shared enterprise DB
39
+ const { createAdapter } = await import('./db/factory.js');
40
+ const db = await createAdapter({
41
+ type: DATABASE_URL.startsWith('postgres') ? 'postgres' : 'sqlite',
42
+ connectionString: DATABASE_URL,
43
+ });
44
+ await db.migrate();
45
+
46
+ // 2. Initialize engine DB
47
+ const { EngineDatabase } = await import('./engine/db-adapter.js');
48
+ const engineDbInterface = db.getEngineDB();
49
+ if (!engineDbInterface) {
50
+ console.error('ERROR: Database does not support engine queries');
51
+ process.exit(1);
52
+ }
53
+ const adapterDialect = db.getDialect();
54
+ const dialectMap: Record<string, string> = {
55
+ sqlite: 'sqlite', postgres: 'postgres', supabase: 'postgres',
56
+ neon: 'postgres', cockroachdb: 'postgres',
57
+ };
58
+ const engineDialect = (dialectMap[adapterDialect] || adapterDialect) as any;
59
+ const engineDb = new EngineDatabase(engineDbInterface, engineDialect);
60
+ await engineDb.migrate();
61
+
62
+ // 3. Load agent config from DB
63
+ const agentRow = await engineDb.query(
64
+ `SELECT id, name, display_name, config, state FROM managed_agents WHERE id = $1`,
65
+ [AGENT_ID]
66
+ );
67
+ if (!agentRow || agentRow.length === 0) {
68
+ console.error(`ERROR: Agent ${AGENT_ID} not found in database`);
69
+ process.exit(1);
70
+ }
71
+ const agent = agentRow[0];
72
+ console.log(` Agent: ${agent.display_name || agent.name}`);
73
+ console.log(` State: ${agent.state}`);
74
+
75
+ // 4. Initialize lifecycle (manages agent state, config decryption)
76
+ const { AgentLifecycle } = await import('./engine/lifecycle.js');
77
+ const lifecycle = new AgentLifecycle(engineDb);
78
+ await lifecycle.loadFromDb();
79
+
80
+ const managed = lifecycle.getAgent(AGENT_ID);
81
+ if (!managed) {
82
+ console.error(`ERROR: Could not load agent ${AGENT_ID} from lifecycle`);
83
+ process.exit(1);
84
+ }
85
+
86
+ const config = managed.config;
87
+ console.log(` Model: ${config.model?.provider}/${config.model?.modelId}`);
88
+
89
+ // 5. Initialize memory manager
90
+ let memoryManager: any;
91
+ try {
92
+ const { AgentMemoryManager } = await import('./engine/agent-memory.js');
93
+ memoryManager = new AgentMemoryManager(engineDb);
94
+ console.log(' Memory: DB-backed');
95
+ } catch { console.log(' Memory: file-based fallback'); }
96
+
97
+ // 6. Load provider API keys from DB settings
98
+ try {
99
+ const settings = await db.getSettings();
100
+ const keys = settings?.modelPricingConfig?.providerApiKeys;
101
+ if (keys && typeof keys === 'object') {
102
+ const { PROVIDER_REGISTRY } = await import('./runtime/providers.js');
103
+ for (const [providerId, apiKey] of Object.entries(keys)) {
104
+ const envVar = (PROVIDER_REGISTRY as any)[providerId]?.envKey;
105
+ if (envVar && apiKey && !process.env[envVar]) {
106
+ process.env[envVar] = apiKey as string;
107
+ console.log(` 🔑 Loaded API key for ${providerId}`);
108
+ }
109
+ }
110
+ }
111
+ } catch {}
112
+
113
+ // 7. Create agent runtime
114
+ const { createAgentRuntime } = await import('./runtime/index.js');
115
+
116
+ const getEmailConfig = (agentId: string) => {
117
+ const m = lifecycle.getAgent(agentId);
118
+ return m?.config?.emailConfig || null;
119
+ };
120
+ const onTokenRefresh = (agentId: string, tokens: any) => {
121
+ const m = lifecycle.getAgent(agentId);
122
+ if (m?.config?.emailConfig) {
123
+ if (tokens.accessToken) m.config.emailConfig.oauthAccessToken = tokens.accessToken;
124
+ if (tokens.refreshToken) m.config.emailConfig.oauthRefreshToken = tokens.refreshToken;
125
+ if (tokens.expiresAt) m.config.emailConfig.oauthTokenExpiry = tokens.expiresAt;
126
+ lifecycle.saveAgent(agentId).catch(() => {});
127
+ }
128
+ };
129
+
130
+ // Parse model from env or agent config
131
+ let defaultModel: any;
132
+ const modelStr = process.env.AGENTICMAIL_MODEL || `${config.model?.provider}/${config.model?.modelId}`;
133
+ if (modelStr && modelStr.includes('/')) {
134
+ const [provider, ...rest] = modelStr.split('/');
135
+ defaultModel = {
136
+ provider,
137
+ modelId: rest.join('/'),
138
+ thinkingLevel: process.env.AGENTICMAIL_THINKING || config.model?.thinkingLevel,
139
+ };
140
+ }
141
+
142
+ const runtime = createAgentRuntime({
143
+ engineDb,
144
+ adminDb: db,
145
+ defaultModel,
146
+ apiKeys: {},
147
+ gatewayEnabled: true,
148
+ getEmailConfig,
149
+ onTokenRefresh,
150
+ agentMemoryManager: memoryManager,
151
+ resumeOnStartup: true,
152
+ });
153
+
154
+ await runtime.start();
155
+ const runtimeApp = runtime.getApp();
156
+
157
+ // 8. Start health check HTTP server
158
+ const app = new Hono();
159
+
160
+ app.get('/health', (c) => c.json({
161
+ status: 'ok',
162
+ agentId: AGENT_ID,
163
+ agentName: agent.display_name || agent.name,
164
+ uptime: process.uptime(),
165
+ }));
166
+
167
+ app.get('/ready', (c) => c.json({ ready: true, agentId: AGENT_ID }));
168
+
169
+ // Mount runtime API if available
170
+ if (runtimeApp) {
171
+ app.route('/api/runtime', runtimeApp);
172
+ }
173
+
174
+ serve({ fetch: app.fetch, port: PORT }, (info) => {
175
+ console.log(`\n✅ Agent runtime started`);
176
+ console.log(` Health: http://localhost:${info.port}/health`);
177
+ console.log(` Runtime: http://localhost:${info.port}/api/runtime`);
178
+ console.log('');
179
+ });
180
+
181
+ // Graceful shutdown
182
+ const shutdown = () => {
183
+ console.log('\n⏳ Shutting down agent...');
184
+ runtime.stop().then(() => db.disconnect()).then(() => {
185
+ console.log('✅ Agent shutdown complete');
186
+ process.exit(0);
187
+ });
188
+ setTimeout(() => process.exit(1), 10_000).unref();
189
+ };
190
+ process.on('SIGINT', shutdown);
191
+ process.on('SIGTERM', shutdown);
192
+
193
+ // 9. Update agent state to 'running'
194
+ try {
195
+ await engineDb.query(
196
+ `UPDATE managed_agents SET state = 'running', updated_at = $1 WHERE id = $2`,
197
+ [new Date().toISOString(), AGENT_ID]
198
+ );
199
+ console.log(' State: running');
200
+ } catch {}
201
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * `npx @agenticmail/enterprise serve`
3
+ *
4
+ * Starts the enterprise server headlessly (no interactive wizard).
5
+ * Reads configuration from environment variables:
6
+ * DATABASE_URL — Postgres/SQLite connection string (required)
7
+ * JWT_SECRET — JWT signing secret (required)
8
+ * PORT — HTTP port (default: 8080)
9
+ */
10
+
11
+ export async function runServe(_args: string[]) {
12
+ const DATABASE_URL = process.env.DATABASE_URL;
13
+ const JWT_SECRET = process.env.JWT_SECRET;
14
+ const PORT = parseInt(process.env.PORT || '8080', 10);
15
+
16
+ if (!DATABASE_URL) { console.error('ERROR: DATABASE_URL environment variable is required'); process.exit(1); }
17
+ if (!JWT_SECRET) { console.error('ERROR: JWT_SECRET environment variable is required'); process.exit(1); }
18
+
19
+ const { createAdapter } = await import('./db/factory.js');
20
+ const { createServer } = await import('./server.js');
21
+
22
+ const db = await createAdapter({
23
+ type: DATABASE_URL.startsWith('postgres') ? 'postgres' : 'sqlite',
24
+ connectionString: DATABASE_URL,
25
+ });
26
+
27
+ await db.migrate();
28
+
29
+ const server = createServer({
30
+ port: PORT,
31
+ db,
32
+ jwtSecret: JWT_SECRET,
33
+ corsOrigins: ['*'],
34
+ });
35
+
36
+ await server.start();
37
+ console.log(`AgenticMail Enterprise server running on :${PORT}`);
38
+ }
package/src/cli.ts CHANGED
@@ -72,6 +72,14 @@ Skill Development:
72
72
  `);
73
73
  break;
74
74
 
75
+ case 'serve':
76
+ import('./cli-serve.js').then(m => m.runServe(args.slice(1))).catch(fatal);
77
+ break;
78
+
79
+ case 'agent':
80
+ import('./cli-agent.js').then(m => m.runAgent(args.slice(1))).catch(fatal);
81
+ break;
82
+
75
83
  case 'setup':
76
84
  default:
77
85
  import('./setup/index.js').then(m => m.runSetupWizard()).catch(fatal);
@@ -451,23 +451,19 @@ export class DeploymentEngine {
451
451
  }
452
452
  }
453
453
 
454
- // 2. Generate workspace files and encode as base64 init script
454
+ // 2. Build environment variables agent reads config from shared DB
455
455
  emit('configure', 'started', 'Preparing agent configuration...');
456
- const workspace = this.configGen.generateWorkspace(config);
457
- const initCommands = Object.entries(workspace).map(([file, content]) => {
458
- const b64 = Buffer.from(content).toString('base64');
459
- return `echo "${b64}" | base64 -d > /workspace/${file}`;
460
- }).join(' && ');
461
-
462
- // Build environment variables for the agent
463
456
  const env: Record<string, string> = {
464
457
  NODE_ENV: 'production',
465
- AGENTICMAIL_MODEL: `${config.model.provider}/${config.model.modelId}`,
466
458
  AGENTICMAIL_AGENT_ID: config.id,
467
459
  AGENTICMAIL_AGENT_NAME: config.displayName || config.name,
460
+ AGENTICMAIL_MODEL: `${config.model?.provider || 'anthropic'}/${config.model?.modelId || 'claude-sonnet-4-20250514'}`,
468
461
  PORT: '3000',
469
462
  };
470
- if (config.model.thinkingLevel) env.AGENTICMAIL_THINKING = config.model.thinkingLevel;
463
+ if (config.model?.thinkingLevel) env.AGENTICMAIL_THINKING = config.model.thinkingLevel;
464
+ // Pass shared DB credentials so agent connects to the same enterprise DB
465
+ if (process.env.DATABASE_URL) env.DATABASE_URL = process.env.DATABASE_URL;
466
+ if (process.env.JWT_SECRET) env.JWT_SECRET = process.env.JWT_SECRET;
471
467
  emit('configure', 'completed', 'Configuration ready');
472
468
 
473
469
  // 3. Check for existing machines — update if found, create if not
@@ -478,8 +474,8 @@ export class DeploymentEngine {
478
474
  env,
479
475
  services: [{
480
476
  ports: [
481
- { port: 443, handlers: ['tls', 'http'], force_https: true },
482
- { port: 80, handlers: ['http'] },
477
+ { port: 443, handlers: ['tls', 'http'] },
478
+ { port: 80, handlers: ['http'], force_https: true },
483
479
  ],
484
480
  protocol: 'tcp',
485
481
  internal_port: 3000,
@@ -490,7 +486,7 @@ export class DeploymentEngine {
490
486
  memory_mb: size.includes('2x') ? 1024 : 512,
491
487
  },
492
488
  init: {
493
- cmd: ['sh', '-c', `mkdir -p /workspace && ${initCommands || 'true'} && npx @agenticmail/enterprise start`],
489
+ cmd: ['sh', '-c', 'npx --yes @agenticmail/enterprise agent'],
494
490
  },
495
491
  auto_destroy: false,
496
492
  restart: { policy: 'always' },