@agenticmail/enterprise 0.5.80 → 0.5.82
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/chunk-34JUBP5Q.js +9107 -0
- package/dist/chunk-4F3OU3JP.js +898 -0
- package/dist/chunk-BTSK5YLA.js +15035 -0
- package/dist/chunk-CFEPEV5P.js +898 -0
- package/dist/chunk-HP2BGRVX.js +15035 -0
- package/dist/chunk-TQYCMFOC.js +2387 -0
- package/dist/chunk-UJFEKPLU.js +2191 -0
- package/dist/chunk-XE6U6O6I.js +2191 -0
- package/dist/cli.js +1 -1
- package/dist/dashboard/pages/agent-detail.js +466 -98
- package/dist/db-adapter-45VLU6DA.js +7 -0
- package/dist/index.js +5 -5
- package/dist/routes-JRYIFCOS.js +6759 -0
- package/dist/routes-YPPF3NE7.js +6759 -0
- package/dist/runtime-4IEMMVEK.js +47 -0
- package/dist/runtime-YCSAKNM7.js +47 -0
- package/dist/server-4PWWE5OI.js +12 -0
- package/dist/server-YEI32L2Q.js +12 -0
- package/dist/setup-CEXMJIEB.js +20 -0
- package/dist/setup-OBJMVWSP.js +20 -0
- package/package.json +1 -1
- package/src/dashboard/pages/agent-detail.js +466 -98
- package/src/engine/agent-routes.ts +93 -0
- package/src/engine/db-adapter.ts +8 -2
- package/src/engine/lifecycle.ts +10 -1
|
@@ -927,6 +927,99 @@ export function createAgentRoutes(opts: {
|
|
|
927
927
|
return c.json({ config: managed.config?.browserConfig || {} });
|
|
928
928
|
});
|
|
929
929
|
|
|
930
|
+
router.post('/bridge/agents/:id/browser-config/test', async (c) => {
|
|
931
|
+
const agentId = c.req.param('id');
|
|
932
|
+
const managed = lifecycle.getAgent(agentId);
|
|
933
|
+
if (!managed) return c.json({ error: 'Agent not found' }, 404);
|
|
934
|
+
|
|
935
|
+
const cfg = managed.config?.browserConfig || {};
|
|
936
|
+
const provider = cfg.provider || 'local';
|
|
937
|
+
|
|
938
|
+
try {
|
|
939
|
+
if (provider === 'local') {
|
|
940
|
+
// Test local Chromium availability
|
|
941
|
+
try {
|
|
942
|
+
const { execSync } = await import('node:child_process');
|
|
943
|
+
const chromePath = cfg.executablePath || process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH || '/usr/bin/chromium';
|
|
944
|
+
const version = execSync(`${chromePath} --version 2>/dev/null || echo "not found"`, { timeout: 5000 }).toString().trim();
|
|
945
|
+
if (version.includes('not found')) {
|
|
946
|
+
return c.json({ error: 'Chromium not found at ' + chromePath });
|
|
947
|
+
}
|
|
948
|
+
return c.json({ ok: true, browserVersion: version, provider: 'local' });
|
|
949
|
+
} catch (e: any) {
|
|
950
|
+
return c.json({ error: 'Chromium not available: ' + e.message });
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
if (provider === 'remote-cdp') {
|
|
955
|
+
if (!cfg.cdpUrl) return c.json({ error: 'CDP URL not configured' });
|
|
956
|
+
try {
|
|
957
|
+
// Extract HTTP URL from WS URL to query /json/version
|
|
958
|
+
const wsUrl = new URL(cfg.cdpUrl);
|
|
959
|
+
const httpUrl = `http://${wsUrl.hostname}:${wsUrl.port}/json/version`;
|
|
960
|
+
const resp = await fetch(httpUrl, { signal: AbortSignal.timeout(cfg.cdpTimeout || 10000) });
|
|
961
|
+
if (!resp.ok) return c.json({ error: `CDP endpoint returned ${resp.status}` });
|
|
962
|
+
const data = await resp.json() as any;
|
|
963
|
+
return c.json({ ok: true, browserVersion: data.Browser || data['User-Agent'], webSocketUrl: data.webSocketDebuggerUrl, provider: 'remote-cdp' });
|
|
964
|
+
} catch (e: any) {
|
|
965
|
+
return c.json({ error: 'Cannot connect to CDP: ' + e.message });
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
if (provider === 'browserless') {
|
|
970
|
+
if (!cfg.browserlessToken) return c.json({ error: 'Browserless API token not configured' });
|
|
971
|
+
const endpoint = cfg.browserlessEndpoint || 'https://chrome.browserless.io';
|
|
972
|
+
try {
|
|
973
|
+
const resp = await fetch(`${endpoint}/config?token=${cfg.browserlessToken}`, { signal: AbortSignal.timeout(10000) });
|
|
974
|
+
if (!resp.ok) return c.json({ error: `Browserless returned ${resp.status}` });
|
|
975
|
+
const data = await resp.json() as any;
|
|
976
|
+
return c.json({ ok: true, browserVersion: data.chrome?.version || 'Connected', provider: 'browserless', concurrent: data.concurrent });
|
|
977
|
+
} catch (e: any) {
|
|
978
|
+
return c.json({ error: 'Cannot connect to Browserless: ' + e.message });
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
if (provider === 'browserbase') {
|
|
983
|
+
if (!cfg.browserbaseApiKey) return c.json({ error: 'Browserbase API key not configured' });
|
|
984
|
+
try {
|
|
985
|
+
const resp = await fetch('https://www.browserbase.com/v1/sessions', {
|
|
986
|
+
method: 'POST',
|
|
987
|
+
headers: { 'x-bb-api-key': cfg.browserbaseApiKey, 'Content-Type': 'application/json' },
|
|
988
|
+
body: JSON.stringify({ projectId: cfg.browserbaseProjectId }),
|
|
989
|
+
signal: AbortSignal.timeout(15000),
|
|
990
|
+
});
|
|
991
|
+
if (!resp.ok) return c.json({ error: `Browserbase returned ${resp.status}` });
|
|
992
|
+
const data = await resp.json() as any;
|
|
993
|
+
return c.json({ ok: true, browserVersion: 'Session created: ' + (data.id || 'OK'), provider: 'browserbase' });
|
|
994
|
+
} catch (e: any) {
|
|
995
|
+
return c.json({ error: 'Cannot connect to Browserbase: ' + e.message });
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
if (provider === 'steel') {
|
|
1000
|
+
if (!cfg.steelApiKey) return c.json({ error: 'Steel API key not configured' });
|
|
1001
|
+
const endpoint = cfg.steelEndpoint || 'https://api.steel.dev';
|
|
1002
|
+
try {
|
|
1003
|
+
const resp = await fetch(`${endpoint}/v1/sessions`, {
|
|
1004
|
+
method: 'POST',
|
|
1005
|
+
headers: { 'Authorization': `Bearer ${cfg.steelApiKey}`, 'Content-Type': 'application/json' },
|
|
1006
|
+
body: JSON.stringify({ timeout: 60 }),
|
|
1007
|
+
signal: AbortSignal.timeout(15000),
|
|
1008
|
+
});
|
|
1009
|
+
if (!resp.ok) return c.json({ error: `Steel returned ${resp.status}` });
|
|
1010
|
+
const data = await resp.json() as any;
|
|
1011
|
+
return c.json({ ok: true, browserVersion: 'Session: ' + (data.id || 'OK'), provider: 'steel' });
|
|
1012
|
+
} catch (e: any) {
|
|
1013
|
+
return c.json({ error: 'Cannot connect to Steel: ' + e.message });
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
return c.json({ ok: true, provider, note: 'Connection test not implemented for this provider' });
|
|
1018
|
+
} catch (e: any) {
|
|
1019
|
+
return c.json({ error: e.message });
|
|
1020
|
+
}
|
|
1021
|
+
});
|
|
1022
|
+
|
|
930
1023
|
router.put('/bridge/agents/:id/browser-config', async (c) => {
|
|
931
1024
|
const agentId = c.req.param('id');
|
|
932
1025
|
const managed = lifecycle.getAgent(agentId);
|
package/src/engine/db-adapter.ts
CHANGED
|
@@ -1022,10 +1022,11 @@ export class EngineDatabase {
|
|
|
1022
1022
|
}
|
|
1023
1023
|
|
|
1024
1024
|
private rowToManagedAgent(row: any): ManagedAgent {
|
|
1025
|
-
|
|
1025
|
+
const config = sj(row.config);
|
|
1026
|
+
const agent: ManagedAgent = {
|
|
1026
1027
|
id: row.id,
|
|
1027
1028
|
orgId: row.org_id,
|
|
1028
|
-
config
|
|
1029
|
+
config,
|
|
1029
1030
|
state: row.state,
|
|
1030
1031
|
stateHistory: [], // Loaded separately via getStateHistory
|
|
1031
1032
|
health: sj(row.health || '{}'),
|
|
@@ -1036,6 +1037,11 @@ export class EngineDatabase {
|
|
|
1036
1037
|
lastHealthCheckAt: row.last_health_check_at,
|
|
1037
1038
|
version: row.version,
|
|
1038
1039
|
};
|
|
1040
|
+
// Restore budgetConfig from config JSON
|
|
1041
|
+
if ((config as any)?.budgetConfig) {
|
|
1042
|
+
agent.budgetConfig = (config as any).budgetConfig;
|
|
1043
|
+
}
|
|
1044
|
+
return agent;
|
|
1039
1045
|
}
|
|
1040
1046
|
|
|
1041
1047
|
private rowToOrg(row: any): Organization {
|
package/src/engine/lifecycle.ts
CHANGED
|
@@ -708,6 +708,9 @@ export class AgentLifecycleManager {
|
|
|
708
708
|
const agent = this.agents.get(agentId);
|
|
709
709
|
if (!agent) throw new Error(`Agent ${agentId} not found`);
|
|
710
710
|
agent.budgetConfig = config;
|
|
711
|
+
// Also store in config JSON so it survives DB round-trips
|
|
712
|
+
if (!agent.config) agent.config = {} as any;
|
|
713
|
+
(agent.config as any).budgetConfig = config;
|
|
711
714
|
agent.updatedAt = new Date().toISOString();
|
|
712
715
|
await this.persistAgent(agent);
|
|
713
716
|
}
|
|
@@ -716,7 +719,13 @@ export class AgentLifecycleManager {
|
|
|
716
719
|
* Get per-agent budget configuration
|
|
717
720
|
*/
|
|
718
721
|
getBudgetConfig(agentId: string): AgentBudgetConfig | undefined {
|
|
719
|
-
|
|
722
|
+
const agent = this.agents.get(agentId);
|
|
723
|
+
if (!agent) return undefined;
|
|
724
|
+
// Restore from config JSON if not on top-level
|
|
725
|
+
if (!agent.budgetConfig && (agent.config as any)?.budgetConfig) {
|
|
726
|
+
agent.budgetConfig = (agent.config as any).budgetConfig;
|
|
727
|
+
}
|
|
728
|
+
return agent.budgetConfig;
|
|
720
729
|
}
|
|
721
730
|
|
|
722
731
|
/**
|