agent-relay 1.0.21 → 1.1.0
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/bridge/shadow-cli.d.ts +17 -0
- package/dist/bridge/shadow-cli.d.ts.map +1 -0
- package/dist/bridge/shadow-cli.js +75 -0
- package/dist/bridge/shadow-cli.js.map +1 -0
- package/dist/bridge/shadow-config.d.ts +87 -0
- package/dist/bridge/shadow-config.d.ts.map +1 -0
- package/dist/bridge/shadow-config.js +134 -0
- package/dist/bridge/shadow-config.js.map +1 -0
- package/dist/bridge/spawner.d.ts +15 -1
- package/dist/bridge/spawner.d.ts.map +1 -1
- package/dist/bridge/spawner.js +164 -4
- package/dist/bridge/spawner.js.map +1 -1
- package/dist/bridge/types.d.ts +55 -0
- package/dist/bridge/types.d.ts.map +1 -1
- package/dist/cli/index.js +796 -11
- package/dist/cli/index.js.map +1 -1
- package/dist/cloud/api/auth.d.ts +19 -0
- package/dist/cloud/api/auth.d.ts.map +1 -0
- package/dist/cloud/api/auth.js +216 -0
- package/dist/cloud/api/auth.js.map +1 -0
- package/dist/cloud/api/billing.d.ts +17 -0
- package/dist/cloud/api/billing.d.ts.map +1 -0
- package/dist/cloud/api/billing.js +353 -0
- package/dist/cloud/api/billing.js.map +1 -0
- package/dist/cloud/api/coordinators.d.ts +8 -0
- package/dist/cloud/api/coordinators.d.ts.map +1 -0
- package/dist/cloud/api/coordinators.js +347 -0
- package/dist/cloud/api/coordinators.js.map +1 -0
- package/dist/cloud/api/daemons.d.ts +12 -0
- package/dist/cloud/api/daemons.d.ts.map +1 -0
- package/dist/cloud/api/daemons.js +320 -0
- package/dist/cloud/api/daemons.js.map +1 -0
- package/dist/cloud/api/middleware/planLimits.d.ts +36 -0
- package/dist/cloud/api/middleware/planLimits.d.ts.map +1 -0
- package/dist/cloud/api/middleware/planLimits.js +164 -0
- package/dist/cloud/api/middleware/planLimits.js.map +1 -0
- package/dist/cloud/api/onboarding.d.ts +8 -0
- package/dist/cloud/api/onboarding.d.ts.map +1 -0
- package/dist/cloud/api/onboarding.js +407 -0
- package/dist/cloud/api/onboarding.js.map +1 -0
- package/dist/cloud/api/providers.d.ts +7 -0
- package/dist/cloud/api/providers.d.ts.map +1 -0
- package/dist/cloud/api/providers.js +435 -0
- package/dist/cloud/api/providers.js.map +1 -0
- package/dist/cloud/api/repos.d.ts +7 -0
- package/dist/cloud/api/repos.d.ts.map +1 -0
- package/dist/cloud/api/repos.js +314 -0
- package/dist/cloud/api/repos.js.map +1 -0
- package/dist/cloud/api/teams.d.ts +7 -0
- package/dist/cloud/api/teams.d.ts.map +1 -0
- package/dist/cloud/api/teams.js +279 -0
- package/dist/cloud/api/teams.js.map +1 -0
- package/dist/cloud/api/usage.d.ts +7 -0
- package/dist/cloud/api/usage.d.ts.map +1 -0
- package/dist/cloud/api/usage.js +98 -0
- package/dist/cloud/api/usage.js.map +1 -0
- package/dist/cloud/api/workspaces.d.ts +7 -0
- package/dist/cloud/api/workspaces.d.ts.map +1 -0
- package/dist/cloud/api/workspaces.js +510 -0
- package/dist/cloud/api/workspaces.js.map +1 -0
- package/dist/cloud/billing/index.d.ts +9 -0
- package/dist/cloud/billing/index.d.ts.map +1 -0
- package/dist/cloud/billing/index.js +9 -0
- package/dist/cloud/billing/index.js.map +1 -0
- package/dist/cloud/billing/plans.d.ts +39 -0
- package/dist/cloud/billing/plans.d.ts.map +1 -0
- package/dist/cloud/billing/plans.js +232 -0
- package/dist/cloud/billing/plans.js.map +1 -0
- package/dist/cloud/billing/service.d.ts +80 -0
- package/dist/cloud/billing/service.d.ts.map +1 -0
- package/dist/cloud/billing/service.js +388 -0
- package/dist/cloud/billing/service.js.map +1 -0
- package/dist/cloud/billing/types.d.ts +135 -0
- package/dist/cloud/billing/types.d.ts.map +1 -0
- package/dist/cloud/billing/types.js +7 -0
- package/dist/cloud/billing/types.js.map +1 -0
- package/dist/cloud/config.d.ts +59 -0
- package/dist/cloud/config.d.ts.map +1 -0
- package/dist/cloud/config.js +83 -0
- package/dist/cloud/config.js.map +1 -0
- package/dist/cloud/db/drizzle.d.ts +132 -0
- package/dist/cloud/db/drizzle.d.ts.map +1 -0
- package/dist/cloud/db/drizzle.js +613 -0
- package/dist/cloud/db/drizzle.js.map +1 -0
- package/dist/cloud/db/index.d.ts +30 -0
- package/dist/cloud/db/index.d.ts.map +1 -0
- package/dist/cloud/db/index.js +44 -0
- package/dist/cloud/db/index.js.map +1 -0
- package/dist/cloud/db/schema.d.ts +1792 -0
- package/dist/cloud/db/schema.d.ts.map +1 -0
- package/dist/cloud/db/schema.js +234 -0
- package/dist/cloud/db/schema.js.map +1 -0
- package/dist/cloud/index.d.ts +11 -0
- package/dist/cloud/index.d.ts.map +1 -0
- package/dist/cloud/index.js +37 -0
- package/dist/cloud/index.js.map +1 -0
- package/dist/cloud/provisioner/index.d.ts +51 -0
- package/dist/cloud/provisioner/index.d.ts.map +1 -0
- package/dist/cloud/provisioner/index.js +676 -0
- package/dist/cloud/provisioner/index.js.map +1 -0
- package/dist/cloud/server.d.ts +16 -0
- package/dist/cloud/server.d.ts.map +1 -0
- package/dist/cloud/server.js +190 -0
- package/dist/cloud/server.js.map +1 -0
- package/dist/cloud/services/coordinator.d.ts +62 -0
- package/dist/cloud/services/coordinator.d.ts.map +1 -0
- package/dist/cloud/services/coordinator.js +389 -0
- package/dist/cloud/services/coordinator.js.map +1 -0
- package/dist/cloud/services/planLimits.d.ts +110 -0
- package/dist/cloud/services/planLimits.d.ts.map +1 -0
- package/dist/cloud/services/planLimits.js +254 -0
- package/dist/cloud/services/planLimits.js.map +1 -0
- package/dist/cloud/vault/index.d.ts +76 -0
- package/dist/cloud/vault/index.d.ts.map +1 -0
- package/dist/cloud/vault/index.js +219 -0
- package/dist/cloud/vault/index.js.map +1 -0
- package/dist/daemon/agent-manager.d.ts +87 -0
- package/dist/daemon/agent-manager.d.ts.map +1 -0
- package/dist/daemon/agent-manager.js +412 -0
- package/dist/daemon/agent-manager.js.map +1 -0
- package/dist/daemon/agent-registry.d.ts +2 -0
- package/dist/daemon/agent-registry.d.ts.map +1 -1
- package/dist/daemon/agent-registry.js +3 -0
- package/dist/daemon/agent-registry.js.map +1 -1
- package/dist/daemon/api.d.ts +69 -0
- package/dist/daemon/api.d.ts.map +1 -0
- package/dist/daemon/api.js +425 -0
- package/dist/daemon/api.js.map +1 -0
- package/dist/daemon/cloud-sync.d.ts +101 -0
- package/dist/daemon/cloud-sync.d.ts.map +1 -0
- package/dist/daemon/cloud-sync.js +261 -0
- package/dist/daemon/cloud-sync.js.map +1 -0
- package/dist/daemon/index.d.ts +4 -0
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +6 -0
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/orchestrator.d.ts +155 -0
- package/dist/daemon/orchestrator.d.ts.map +1 -0
- package/dist/daemon/orchestrator.js +736 -0
- package/dist/daemon/orchestrator.js.map +1 -0
- package/dist/daemon/router.d.ts +24 -0
- package/dist/daemon/router.d.ts.map +1 -1
- package/dist/daemon/router.js +71 -1
- package/dist/daemon/router.js.map +1 -1
- package/dist/daemon/server.d.ts +37 -0
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +191 -16
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/types.d.ts +127 -0
- package/dist/daemon/types.d.ts.map +1 -0
- package/dist/daemon/types.js +6 -0
- package/dist/daemon/types.js.map +1 -0
- package/dist/daemon/workspace-manager.d.ts +75 -0
- package/dist/daemon/workspace-manager.d.ts.map +1 -0
- package/dist/daemon/workspace-manager.js +289 -0
- package/dist/daemon/workspace-manager.js.map +1 -0
- package/dist/dashboard/out/404.html +1 -1
- package/dist/dashboard/out/_next/static/chunks/693-7b3301d8f6bc5014.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/713-f78477eb185f1f4d.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/766-e53e1cfe39b0b5b5.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/900-037c64bfd797fb2a.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/app/page-e3d9e1f4466b9bae.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/history/page-b6edd4dde8d08194.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/layout-2433bb48965f4333.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-e68825a81db67ba1.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/page-cc108bf68c8a657f.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/app/pricing/page-d80e03a5297f95b6.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/main-app-5d692157a8eb1fd9.js +1 -0
- package/dist/dashboard/out/_next/static/chunks/{main-e0a1f53fe0617a63.js → main-c2f423b9c9f4591b.js} +1 -1
- package/dist/dashboard/out/_next/static/chunks/{webpack-c81f7fd28659d64f.js → webpack-a5acc2831d094776.js} +1 -1
- package/dist/dashboard/out/_next/static/css/79b80143647a07d7.css +1 -0
- package/dist/dashboard/out/_next/static/css/8cf277370ad48cfe.css +1 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-128.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-256.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-32.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-512.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-64.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo.svg +45 -0
- package/dist/dashboard/out/alt-logos/logo.svg +38 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-128.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-256.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-32.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-512.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-64.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo.svg +38 -0
- package/dist/dashboard/out/app.html +14 -0
- package/dist/dashboard/out/app.txt +7 -0
- package/dist/dashboard/out/history.html +1 -0
- package/dist/dashboard/out/history.txt +7 -0
- package/dist/dashboard/out/index.html +1 -1
- package/dist/dashboard/out/index.txt +2 -2
- package/dist/dashboard/out/metrics.html +1 -515
- package/dist/dashboard/out/metrics.txt +2 -2
- package/dist/dashboard/out/pricing.html +13 -0
- package/dist/dashboard/out/pricing.txt +7 -0
- package/dist/dashboard-server/metrics.d.ts.map +1 -1
- package/dist/dashboard-server/metrics.js +3 -2
- package/dist/dashboard-server/metrics.js.map +1 -1
- package/dist/dashboard-server/server.d.ts.map +1 -1
- package/dist/dashboard-server/server.js +1279 -56
- package/dist/dashboard-server/server.js.map +1 -1
- package/dist/protocol/types.d.ts +10 -1
- package/dist/protocol/types.d.ts.map +1 -1
- package/dist/resiliency/context-persistence.d.ts +140 -0
- package/dist/resiliency/context-persistence.d.ts.map +1 -0
- package/dist/resiliency/context-persistence.js +397 -0
- package/dist/resiliency/context-persistence.js.map +1 -0
- package/dist/resiliency/health-monitor.d.ts +97 -0
- package/dist/resiliency/health-monitor.d.ts.map +1 -0
- package/dist/resiliency/health-monitor.js +291 -0
- package/dist/resiliency/health-monitor.js.map +1 -0
- package/dist/resiliency/index.d.ts +63 -0
- package/dist/resiliency/index.d.ts.map +1 -0
- package/dist/resiliency/index.js +63 -0
- package/dist/resiliency/index.js.map +1 -0
- package/dist/resiliency/logger.d.ts +114 -0
- package/dist/resiliency/logger.d.ts.map +1 -0
- package/dist/resiliency/logger.js +250 -0
- package/dist/resiliency/logger.js.map +1 -0
- package/dist/resiliency/metrics.d.ts +115 -0
- package/dist/resiliency/metrics.d.ts.map +1 -0
- package/dist/resiliency/metrics.js +239 -0
- package/dist/resiliency/metrics.js.map +1 -0
- package/dist/resiliency/provider-context.d.ts +100 -0
- package/dist/resiliency/provider-context.d.ts.map +1 -0
- package/dist/resiliency/provider-context.js +360 -0
- package/dist/resiliency/provider-context.js.map +1 -0
- package/dist/resiliency/supervisor.d.ts +109 -0
- package/dist/resiliency/supervisor.d.ts.map +1 -0
- package/dist/resiliency/supervisor.js +337 -0
- package/dist/resiliency/supervisor.js.map +1 -0
- package/dist/storage/adapter.d.ts +2 -0
- package/dist/storage/adapter.d.ts.map +1 -1
- package/dist/storage/adapter.js +12 -2
- package/dist/storage/adapter.js.map +1 -1
- package/dist/storage/sqlite-adapter.d.ts.map +1 -1
- package/dist/storage/sqlite-adapter.js +18 -14
- package/dist/storage/sqlite-adapter.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/logger.d.ts +40 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +84 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/wrapper/client.d.ts +16 -1
- package/dist/wrapper/client.d.ts.map +1 -1
- package/dist/wrapper/client.js +32 -1
- package/dist/wrapper/client.js.map +1 -1
- package/dist/wrapper/parser.d.ts +3 -0
- package/dist/wrapper/parser.d.ts.map +1 -1
- package/dist/wrapper/parser.js +121 -18
- package/dist/wrapper/parser.js.map +1 -1
- package/dist/wrapper/pty-wrapper.d.ts +28 -1
- package/dist/wrapper/pty-wrapper.d.ts.map +1 -1
- package/dist/wrapper/pty-wrapper.js +166 -30
- package/dist/wrapper/pty-wrapper.js.map +1 -1
- package/dist/wrapper/tmux-wrapper.d.ts +5 -0
- package/dist/wrapper/tmux-wrapper.d.ts.map +1 -1
- package/dist/wrapper/tmux-wrapper.js +58 -18
- package/dist/wrapper/tmux-wrapper.js.map +1 -1
- package/docs/CLOUD-ARCHITECTURE.md +652 -0
- package/docs/CLOUD-ONBOARDING-DESIGN.md +1983 -0
- package/docs/TESTING_PRESENCE_FEATURES.md +327 -0
- package/docs/agent-relay-snippet.md +107 -4
- package/docs/guides/CLOUD.md +236 -0
- package/docs/guides/LOCAL.md +535 -0
- package/docs/guides/SELF-HOSTED.md +494 -0
- package/docs/proposals/shadow-as-subagent.md +765 -0
- package/docs/proposals/slack-bot-integration.md +1457 -0
- package/package.json +33 -4
- package/dist/dashboard/out/_next/static/chunks/app/layout-c9d8c5d95e48c6bf.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-8aa9936bc6c771ab.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/page-49055e5d2b5e34ec.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/main-app-bae2e535de00de50.js +0 -1
- package/dist/dashboard/out/_next/static/css/50ed6996e3df7bdd.css +0 -1
- /package/dist/dashboard/out/_next/static/{gZXwjIKGDKJ0hiTH-HMeJ → 6HHWb2ZmnJ4OSm0zUP7h4}/_buildManifest.js +0 -0
- /package/dist/dashboard/out/_next/static/{gZXwjIKGDKJ0hiTH-HMeJ → 6HHWb2ZmnJ4OSm0zUP7h4}/_ssgManifest.js +0 -0
- /package/dist/dashboard/out/_next/static/chunks/{117-3bef7b19f3e60751.js → 117-b2cd8d6485aacf2b.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/{648-6cf686106c891ad3.js → 648-8f3f26864ce515e5.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/app/_not-found/{page-8ff6572bc7c9bc61.js → page-0b990dbb71d72a98.js} +0 -0
- /package/dist/dashboard/out/_next/static/chunks/{fd9d1056-26bd8d656b496dba.js → fd9d1056-bf46c09eb57e019c.js} +0 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Health Monitor
|
|
3
|
+
*
|
|
4
|
+
* Monitors spawned agent processes and ensures they stay alive.
|
|
5
|
+
* - Periodic health checks (process liveness)
|
|
6
|
+
* - Auto-restart on crash
|
|
7
|
+
* - Death detection and logging
|
|
8
|
+
* - Metrics collection
|
|
9
|
+
*/
|
|
10
|
+
import { EventEmitter } from 'events';
|
|
11
|
+
const DEFAULT_CONFIG = {
|
|
12
|
+
checkIntervalMs: 5000,
|
|
13
|
+
responseTimeoutMs: 10000,
|
|
14
|
+
maxRestarts: 5,
|
|
15
|
+
restartCooldownMs: 2000,
|
|
16
|
+
maxConsecutiveFailures: 3,
|
|
17
|
+
};
|
|
18
|
+
export class AgentHealthMonitor extends EventEmitter {
|
|
19
|
+
agents = new Map();
|
|
20
|
+
health = new Map();
|
|
21
|
+
intervalId;
|
|
22
|
+
config;
|
|
23
|
+
isRunning = false;
|
|
24
|
+
constructor(config = {}) {
|
|
25
|
+
super();
|
|
26
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Register an agent for health monitoring
|
|
30
|
+
*/
|
|
31
|
+
register(agent) {
|
|
32
|
+
this.agents.set(agent.name, agent);
|
|
33
|
+
this.health.set(agent.name, {
|
|
34
|
+
name: agent.name,
|
|
35
|
+
pid: agent.pid,
|
|
36
|
+
status: 'healthy',
|
|
37
|
+
lastHealthCheck: new Date(),
|
|
38
|
+
lastResponse: new Date(),
|
|
39
|
+
restartCount: 0,
|
|
40
|
+
consecutiveFailures: 0,
|
|
41
|
+
uptime: 0,
|
|
42
|
+
startedAt: new Date(),
|
|
43
|
+
});
|
|
44
|
+
this.emit('registered', { name: agent.name, pid: agent.pid });
|
|
45
|
+
this.log('info', `Registered agent for health monitoring: ${agent.name} (PID: ${agent.pid})`);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Unregister an agent from health monitoring
|
|
49
|
+
*/
|
|
50
|
+
unregister(name) {
|
|
51
|
+
this.agents.delete(name);
|
|
52
|
+
this.health.delete(name);
|
|
53
|
+
this.emit('unregistered', { name });
|
|
54
|
+
this.log('info', `Unregistered agent: ${name}`);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Start the health monitoring loop
|
|
58
|
+
*/
|
|
59
|
+
start() {
|
|
60
|
+
if (this.isRunning)
|
|
61
|
+
return;
|
|
62
|
+
this.isRunning = true;
|
|
63
|
+
this.log('info', 'Health monitor started', {
|
|
64
|
+
checkInterval: this.config.checkIntervalMs,
|
|
65
|
+
maxRestarts: this.config.maxRestarts,
|
|
66
|
+
});
|
|
67
|
+
this.intervalId = setInterval(() => {
|
|
68
|
+
this.checkAll();
|
|
69
|
+
}, this.config.checkIntervalMs);
|
|
70
|
+
// Initial check
|
|
71
|
+
this.checkAll();
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Stop the health monitoring loop
|
|
75
|
+
*/
|
|
76
|
+
stop() {
|
|
77
|
+
if (this.intervalId) {
|
|
78
|
+
clearInterval(this.intervalId);
|
|
79
|
+
this.intervalId = undefined;
|
|
80
|
+
}
|
|
81
|
+
this.isRunning = false;
|
|
82
|
+
this.log('info', 'Health monitor stopped');
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get health status for all agents
|
|
86
|
+
*/
|
|
87
|
+
getAll() {
|
|
88
|
+
return Array.from(this.health.values()).map((h) => ({
|
|
89
|
+
...h,
|
|
90
|
+
uptime: Date.now() - h.startedAt.getTime(),
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get health status for a specific agent
|
|
95
|
+
*/
|
|
96
|
+
get(name) {
|
|
97
|
+
const health = this.health.get(name);
|
|
98
|
+
if (health) {
|
|
99
|
+
return { ...health, uptime: Date.now() - health.startedAt.getTime() };
|
|
100
|
+
}
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Check health of all registered agents
|
|
105
|
+
*/
|
|
106
|
+
async checkAll() {
|
|
107
|
+
const checks = Array.from(this.agents.entries()).map(([name, agent]) => this.checkAgent(name, agent));
|
|
108
|
+
await Promise.all(checks);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Check health of a single agent
|
|
112
|
+
*/
|
|
113
|
+
async checkAgent(name, agent) {
|
|
114
|
+
const health = this.health.get(name);
|
|
115
|
+
if (!health)
|
|
116
|
+
return;
|
|
117
|
+
health.lastHealthCheck = new Date();
|
|
118
|
+
try {
|
|
119
|
+
// First check: Is the process alive?
|
|
120
|
+
const isAlive = this.isProcessAlive(agent.pid);
|
|
121
|
+
if (!isAlive) {
|
|
122
|
+
await this.handleDeath(name, agent, health, 'Process not found');
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// Second check: Does it respond to health check?
|
|
126
|
+
if (agent.sendHealthCheck) {
|
|
127
|
+
const responded = await Promise.race([
|
|
128
|
+
agent.sendHealthCheck(),
|
|
129
|
+
new Promise((resolve) => setTimeout(() => resolve(false), this.config.responseTimeoutMs)),
|
|
130
|
+
]);
|
|
131
|
+
if (!responded) {
|
|
132
|
+
health.consecutiveFailures++;
|
|
133
|
+
this.log('warn', `Agent unresponsive: ${name}`, {
|
|
134
|
+
failures: health.consecutiveFailures,
|
|
135
|
+
max: this.config.maxConsecutiveFailures,
|
|
136
|
+
});
|
|
137
|
+
if (health.consecutiveFailures >= this.config.maxConsecutiveFailures) {
|
|
138
|
+
health.status = 'unresponsive';
|
|
139
|
+
await this.handleDeath(name, agent, health, 'Unresponsive after multiple health checks');
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
health.status = 'unresponsive';
|
|
143
|
+
this.emit('unhealthy', { name, health });
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Get memory/CPU usage if available
|
|
149
|
+
try {
|
|
150
|
+
const usage = await this.getProcessUsage(agent.pid);
|
|
151
|
+
health.memoryUsage = usage.memory;
|
|
152
|
+
health.cpuUsage = usage.cpu;
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Ignore usage errors
|
|
156
|
+
}
|
|
157
|
+
// All good
|
|
158
|
+
health.status = 'healthy';
|
|
159
|
+
health.lastResponse = new Date();
|
|
160
|
+
health.consecutiveFailures = 0;
|
|
161
|
+
this.emit('healthy', { name, health });
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
health.consecutiveFailures++;
|
|
165
|
+
health.lastError = error instanceof Error ? error.message : String(error);
|
|
166
|
+
this.log('error', `Health check error for ${name}`, { error: health.lastError });
|
|
167
|
+
if (health.consecutiveFailures >= this.config.maxConsecutiveFailures) {
|
|
168
|
+
await this.handleDeath(name, agent, health, health.lastError);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Handle agent death - attempt restart or mark as dead
|
|
174
|
+
*/
|
|
175
|
+
async handleDeath(name, agent, health, reason) {
|
|
176
|
+
this.log('error', `Agent died: ${name}`, {
|
|
177
|
+
reason,
|
|
178
|
+
restartCount: health.restartCount,
|
|
179
|
+
maxRestarts: this.config.maxRestarts,
|
|
180
|
+
});
|
|
181
|
+
this.emit('died', { name, reason, restartCount: health.restartCount });
|
|
182
|
+
// Check if we should attempt restart
|
|
183
|
+
if (health.restartCount >= this.config.maxRestarts) {
|
|
184
|
+
health.status = 'dead';
|
|
185
|
+
health.lastError = `Exceeded max restarts (${this.config.maxRestarts}): ${reason}`;
|
|
186
|
+
this.log('error', `Agent permanently dead: ${name}`, { reason: health.lastError });
|
|
187
|
+
this.emit('permanentlyDead', { name, health });
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
// Attempt restart
|
|
191
|
+
health.status = 'restarting';
|
|
192
|
+
health.restartCount++;
|
|
193
|
+
this.log('info', `Attempting restart ${health.restartCount}/${this.config.maxRestarts}: ${name}`);
|
|
194
|
+
this.emit('restarting', { name, attempt: health.restartCount });
|
|
195
|
+
// Wait cooldown
|
|
196
|
+
await new Promise((resolve) => setTimeout(resolve, this.config.restartCooldownMs));
|
|
197
|
+
try {
|
|
198
|
+
await agent.restart();
|
|
199
|
+
// Update health after successful restart
|
|
200
|
+
health.status = 'healthy';
|
|
201
|
+
health.consecutiveFailures = 0;
|
|
202
|
+
health.startedAt = new Date();
|
|
203
|
+
health.lastResponse = new Date();
|
|
204
|
+
health.pid = agent.pid;
|
|
205
|
+
this.log('info', `Agent restarted successfully: ${name}`, {
|
|
206
|
+
newPid: agent.pid,
|
|
207
|
+
attempt: health.restartCount,
|
|
208
|
+
});
|
|
209
|
+
this.emit('restarted', { name, pid: agent.pid, attempt: health.restartCount });
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
health.lastError = error instanceof Error ? error.message : String(error);
|
|
213
|
+
this.log('error', `Restart failed: ${name}`, { error: health.lastError });
|
|
214
|
+
this.emit('restartFailed', { name, error: health.lastError });
|
|
215
|
+
// Recursively try again if under limit
|
|
216
|
+
if (health.restartCount < this.config.maxRestarts) {
|
|
217
|
+
await this.handleDeath(name, agent, health, health.lastError);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
health.status = 'dead';
|
|
221
|
+
this.emit('permanentlyDead', { name, health });
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Check if a process is alive by PID
|
|
227
|
+
*/
|
|
228
|
+
isProcessAlive(pid) {
|
|
229
|
+
try {
|
|
230
|
+
// Sending signal 0 checks if process exists without killing it
|
|
231
|
+
process.kill(pid, 0);
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Get memory and CPU usage for a process
|
|
240
|
+
*/
|
|
241
|
+
async getProcessUsage(pid) {
|
|
242
|
+
const { execSync } = await import('child_process');
|
|
243
|
+
try {
|
|
244
|
+
// This works on Linux/Mac
|
|
245
|
+
const output = execSync(`ps -o rss=,pcpu= -p ${pid}`, { encoding: 'utf8' }).trim();
|
|
246
|
+
const [rss, cpu] = output.split(/\s+/);
|
|
247
|
+
return {
|
|
248
|
+
memory: parseInt(rss, 10) * 1024, // RSS in bytes
|
|
249
|
+
cpu: parseFloat(cpu),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
return { memory: 0, cpu: 0 };
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Structured logging
|
|
258
|
+
*/
|
|
259
|
+
log(level, message, context) {
|
|
260
|
+
const entry = {
|
|
261
|
+
timestamp: new Date().toISOString(),
|
|
262
|
+
level,
|
|
263
|
+
component: 'health-monitor',
|
|
264
|
+
message,
|
|
265
|
+
...context,
|
|
266
|
+
};
|
|
267
|
+
this.emit('log', entry);
|
|
268
|
+
// Also log to console with structure
|
|
269
|
+
const prefix = `[health-monitor]`;
|
|
270
|
+
switch (level) {
|
|
271
|
+
case 'info':
|
|
272
|
+
console.log(prefix, message, context ? JSON.stringify(context) : '');
|
|
273
|
+
break;
|
|
274
|
+
case 'warn':
|
|
275
|
+
console.warn(prefix, message, context ? JSON.stringify(context) : '');
|
|
276
|
+
break;
|
|
277
|
+
case 'error':
|
|
278
|
+
console.error(prefix, message, context ? JSON.stringify(context) : '');
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// Singleton instance
|
|
284
|
+
let _monitor = null;
|
|
285
|
+
export function getHealthMonitor(config) {
|
|
286
|
+
if (!_monitor) {
|
|
287
|
+
_monitor = new AgentHealthMonitor(config);
|
|
288
|
+
}
|
|
289
|
+
return _monitor;
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=health-monitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-monitor.js","sourceRoot":"","sources":["../../src/resiliency/health-monitor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Resiliency Module
|
|
3
|
+
*
|
|
4
|
+
* Provides comprehensive health monitoring, auto-restart, logging,
|
|
5
|
+
* metrics, and context persistence for agent-relay agents.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Health monitoring with process liveness checks
|
|
9
|
+
* - Auto-restart on crash with configurable limits
|
|
10
|
+
* - Prometheus-compatible metrics export
|
|
11
|
+
* - Structured JSON logging with rotation
|
|
12
|
+
* - Context persistence across restarts (inspired by Continuous-Claude-v2)
|
|
13
|
+
* - Provider-specific context injection (Claude hooks, Codex config, Gemini instructions)
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { getSupervisor, metrics, createLogger } from './resiliency';
|
|
19
|
+
*
|
|
20
|
+
* // Start the supervisor with context persistence
|
|
21
|
+
* const supervisor = getSupervisor({
|
|
22
|
+
* autoRestart: true,
|
|
23
|
+
* maxRestarts: 5,
|
|
24
|
+
* contextPersistence: {
|
|
25
|
+
* enabled: true,
|
|
26
|
+
* autoInjectOnRestart: true,
|
|
27
|
+
* },
|
|
28
|
+
* });
|
|
29
|
+
* supervisor.start();
|
|
30
|
+
*
|
|
31
|
+
* // Add an agent to supervision
|
|
32
|
+
* supervisor.supervise(
|
|
33
|
+
* {
|
|
34
|
+
* name: 'worker-1',
|
|
35
|
+
* cli: 'claude',
|
|
36
|
+
* pid: 12345,
|
|
37
|
+
* spawnedAt: new Date(),
|
|
38
|
+
* workingDir: '/path/to/repo',
|
|
39
|
+
* provider: 'claude', // or 'codex', 'gemini'
|
|
40
|
+
* },
|
|
41
|
+
* {
|
|
42
|
+
* isAlive: () => process.kill(12345, 0),
|
|
43
|
+
* kill: (sig) => process.kill(12345, sig),
|
|
44
|
+
* restart: async () => { ... },
|
|
45
|
+
* }
|
|
46
|
+
* );
|
|
47
|
+
*
|
|
48
|
+
* // Get metrics
|
|
49
|
+
* console.log(metrics.toPrometheus());
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* Context persistence works differently per provider:
|
|
53
|
+
* - Claude: Uses hooks to inject context into CLAUDE.md
|
|
54
|
+
* - Codex: Uses config for periodic context refresh via system prompt
|
|
55
|
+
* - Gemini: Updates system instruction file
|
|
56
|
+
*/
|
|
57
|
+
export { AgentHealthMonitor, getHealthMonitor, type AgentHealth, type AgentProcess, type HealthMonitorConfig, } from './health-monitor.js';
|
|
58
|
+
export { Logger, createLogger, configure as configureLogging, loggers, type LogLevel, type LogEntry, type LoggerConfig, } from './logger.js';
|
|
59
|
+
export { metrics, type AgentMetrics, type SystemMetrics, type MetricPoint } from './metrics.js';
|
|
60
|
+
export { AgentSupervisor, getSupervisor, type SupervisedAgent, type SupervisorConfig, } from './supervisor.js';
|
|
61
|
+
export { ContextPersistence, getContextPersistence, type AgentState, type Decision, type Artifact, type Handoff, type LedgerEntry, } from './context-persistence.js';
|
|
62
|
+
export { createContextHandler, detectProvider, ClaudeContextHandler, CodexContextHandler, GeminiContextHandler, type ProviderType, type ProviderContextConfig, type ClaudeHooksConfig, type CodexContextConfig, } from './provider-context.js';
|
|
63
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resiliency/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,MAAM,EACN,YAAY,EACZ,SAAS,IAAI,gBAAgB,EAC7B,OAAO,EACP,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhG,OAAO,EACL,eAAe,EACf,aAAa,EACb,KAAK,eAAe,EACpB,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,WAAW,GACjB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACxB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Resiliency Module
|
|
3
|
+
*
|
|
4
|
+
* Provides comprehensive health monitoring, auto-restart, logging,
|
|
5
|
+
* metrics, and context persistence for agent-relay agents.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Health monitoring with process liveness checks
|
|
9
|
+
* - Auto-restart on crash with configurable limits
|
|
10
|
+
* - Prometheus-compatible metrics export
|
|
11
|
+
* - Structured JSON logging with rotation
|
|
12
|
+
* - Context persistence across restarts (inspired by Continuous-Claude-v2)
|
|
13
|
+
* - Provider-specific context injection (Claude hooks, Codex config, Gemini instructions)
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { getSupervisor, metrics, createLogger } from './resiliency';
|
|
19
|
+
*
|
|
20
|
+
* // Start the supervisor with context persistence
|
|
21
|
+
* const supervisor = getSupervisor({
|
|
22
|
+
* autoRestart: true,
|
|
23
|
+
* maxRestarts: 5,
|
|
24
|
+
* contextPersistence: {
|
|
25
|
+
* enabled: true,
|
|
26
|
+
* autoInjectOnRestart: true,
|
|
27
|
+
* },
|
|
28
|
+
* });
|
|
29
|
+
* supervisor.start();
|
|
30
|
+
*
|
|
31
|
+
* // Add an agent to supervision
|
|
32
|
+
* supervisor.supervise(
|
|
33
|
+
* {
|
|
34
|
+
* name: 'worker-1',
|
|
35
|
+
* cli: 'claude',
|
|
36
|
+
* pid: 12345,
|
|
37
|
+
* spawnedAt: new Date(),
|
|
38
|
+
* workingDir: '/path/to/repo',
|
|
39
|
+
* provider: 'claude', // or 'codex', 'gemini'
|
|
40
|
+
* },
|
|
41
|
+
* {
|
|
42
|
+
* isAlive: () => process.kill(12345, 0),
|
|
43
|
+
* kill: (sig) => process.kill(12345, sig),
|
|
44
|
+
* restart: async () => { ... },
|
|
45
|
+
* }
|
|
46
|
+
* );
|
|
47
|
+
*
|
|
48
|
+
* // Get metrics
|
|
49
|
+
* console.log(metrics.toPrometheus());
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* Context persistence works differently per provider:
|
|
53
|
+
* - Claude: Uses hooks to inject context into CLAUDE.md
|
|
54
|
+
* - Codex: Uses config for periodic context refresh via system prompt
|
|
55
|
+
* - Gemini: Updates system instruction file
|
|
56
|
+
*/
|
|
57
|
+
export { AgentHealthMonitor, getHealthMonitor, } from './health-monitor.js';
|
|
58
|
+
export { Logger, createLogger, configure as configureLogging, loggers, } from './logger.js';
|
|
59
|
+
export { metrics } from './metrics.js';
|
|
60
|
+
export { AgentSupervisor, getSupervisor, } from './supervisor.js';
|
|
61
|
+
export { ContextPersistence, getContextPersistence, } from './context-persistence.js';
|
|
62
|
+
export { createContextHandler, detectProvider, ClaudeContextHandler, CodexContextHandler, GeminiContextHandler, } from './provider-context.js';
|
|
63
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resiliency/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GAIjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,MAAM,EACN,YAAY,EACZ,SAAS,IAAI,gBAAgB,EAC7B,OAAO,GAIR,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,EAA2D,MAAM,cAAc,CAAC;AAEhG,OAAO,EACL,eAAe,EACf,aAAa,GAGd,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,kBAAkB,EAClB,qBAAqB,GAMtB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,GAKrB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured Logger
|
|
3
|
+
*
|
|
4
|
+
* Provides consistent, structured logging across agent-relay components.
|
|
5
|
+
* - JSON format for machine parsing
|
|
6
|
+
* - Log levels with filtering
|
|
7
|
+
* - Context propagation (correlation IDs, agent names)
|
|
8
|
+
* - File rotation support
|
|
9
|
+
*/
|
|
10
|
+
import { EventEmitter } from 'events';
|
|
11
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';
|
|
12
|
+
export interface LogEntry {
|
|
13
|
+
timestamp: string;
|
|
14
|
+
level: LogLevel;
|
|
15
|
+
component: string;
|
|
16
|
+
message: string;
|
|
17
|
+
correlationId?: string;
|
|
18
|
+
agentName?: string;
|
|
19
|
+
pid?: number;
|
|
20
|
+
duration?: number;
|
|
21
|
+
error?: {
|
|
22
|
+
name: string;
|
|
23
|
+
message: string;
|
|
24
|
+
stack?: string;
|
|
25
|
+
};
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
export interface LoggerConfig {
|
|
29
|
+
level: LogLevel;
|
|
30
|
+
json: boolean;
|
|
31
|
+
file?: string;
|
|
32
|
+
maxFileSize?: number;
|
|
33
|
+
maxFiles?: number;
|
|
34
|
+
console: boolean;
|
|
35
|
+
}
|
|
36
|
+
export declare class Logger extends EventEmitter {
|
|
37
|
+
private config;
|
|
38
|
+
private component;
|
|
39
|
+
private context;
|
|
40
|
+
private fileStream?;
|
|
41
|
+
private currentFileSize;
|
|
42
|
+
constructor(component: string, config?: Partial<LoggerConfig>);
|
|
43
|
+
/**
|
|
44
|
+
* Create a child logger with additional context
|
|
45
|
+
*/
|
|
46
|
+
child(context: Record<string, unknown>): Logger;
|
|
47
|
+
/**
|
|
48
|
+
* Set context that will be included in all log entries
|
|
49
|
+
*/
|
|
50
|
+
setContext(context: Record<string, unknown>): void;
|
|
51
|
+
/**
|
|
52
|
+
* Log at debug level
|
|
53
|
+
*/
|
|
54
|
+
debug(message: string, context?: Record<string, unknown>): void;
|
|
55
|
+
/**
|
|
56
|
+
* Log at info level
|
|
57
|
+
*/
|
|
58
|
+
info(message: string, context?: Record<string, unknown>): void;
|
|
59
|
+
/**
|
|
60
|
+
* Log at warn level
|
|
61
|
+
*/
|
|
62
|
+
warn(message: string, context?: Record<string, unknown>): void;
|
|
63
|
+
/**
|
|
64
|
+
* Log at error level
|
|
65
|
+
*/
|
|
66
|
+
error(message: string, context?: Record<string, unknown>): void;
|
|
67
|
+
/**
|
|
68
|
+
* Log at fatal level
|
|
69
|
+
*/
|
|
70
|
+
fatal(message: string, context?: Record<string, unknown>): void;
|
|
71
|
+
/**
|
|
72
|
+
* Log with timing (returns function to end timing)
|
|
73
|
+
*/
|
|
74
|
+
time(message: string, context?: Record<string, unknown>): () => void;
|
|
75
|
+
/**
|
|
76
|
+
* Log an error with stack trace
|
|
77
|
+
*/
|
|
78
|
+
logError(error: Error, message?: string, context?: Record<string, unknown>): void;
|
|
79
|
+
/**
|
|
80
|
+
* Core log method
|
|
81
|
+
*/
|
|
82
|
+
private log;
|
|
83
|
+
/**
|
|
84
|
+
* Write to console
|
|
85
|
+
*/
|
|
86
|
+
private writeConsole;
|
|
87
|
+
/**
|
|
88
|
+
* Write to file with rotation
|
|
89
|
+
*/
|
|
90
|
+
private writeFile;
|
|
91
|
+
/**
|
|
92
|
+
* Initialize file stream
|
|
93
|
+
*/
|
|
94
|
+
private initFileStream;
|
|
95
|
+
/**
|
|
96
|
+
* Rotate log file
|
|
97
|
+
*/
|
|
98
|
+
private rotateFile;
|
|
99
|
+
/**
|
|
100
|
+
* Close the logger
|
|
101
|
+
*/
|
|
102
|
+
close(): void;
|
|
103
|
+
}
|
|
104
|
+
export declare function configure(config: Partial<LoggerConfig>): void;
|
|
105
|
+
export declare function createLogger(component: string, config?: Partial<LoggerConfig>): Logger;
|
|
106
|
+
export declare const loggers: {
|
|
107
|
+
daemon: () => Logger;
|
|
108
|
+
spawner: () => Logger;
|
|
109
|
+
router: () => Logger;
|
|
110
|
+
agent: (name: string) => Logger;
|
|
111
|
+
health: () => Logger;
|
|
112
|
+
connection: (id: string) => Logger;
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/resiliency/logger.ts"],"names":[],"mappings":"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"}
|