@agentmeshhq/agent 0.4.2 → 0.4.3
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/LICENSE +21 -0
- package/dist/__tests__/evicted-cleanup.test.d.ts +10 -0
- package/dist/__tests__/evicted-cleanup.test.js +459 -0
- package/dist/__tests__/evicted-cleanup.test.js.map +1 -0
- package/dist/__tests__/local.test.d.ts +1 -0
- package/dist/__tests__/local.test.js +124 -0
- package/dist/__tests__/local.test.js.map +1 -0
- package/dist/__tests__/tmux-send.test.d.ts +10 -0
- package/dist/__tests__/tmux-send.test.js +96 -0
- package/dist/__tests__/tmux-send.test.js.map +1 -0
- package/dist/cli/inbox.d.ts +5 -0
- package/dist/cli/inbox.js +123 -0
- package/dist/cli/inbox.js.map +1 -0
- package/dist/cli/index.js +285 -11
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/issue.d.ts +42 -0
- package/dist/cli/issue.js +297 -0
- package/dist/cli/issue.js.map +1 -0
- package/dist/cli/local.d.ts +27 -6
- package/dist/cli/local.js +319 -36
- package/dist/cli/local.js.map +1 -1
- package/dist/cli/ready.d.ts +5 -0
- package/dist/cli/ready.js +131 -0
- package/dist/cli/ready.js.map +1 -0
- package/dist/cli/sync.d.ts +8 -0
- package/dist/cli/sync.js +154 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli/token.js +242 -9
- package/dist/cli/token.js.map +1 -1
- package/dist/cli/whoami.d.ts +6 -0
- package/dist/cli/whoami.js +109 -5
- package/dist/cli/whoami.js.map +1 -1
- package/dist/core/cleanup/eligibility.d.ts +41 -0
- package/dist/core/cleanup/eligibility.js +64 -0
- package/dist/core/cleanup/eligibility.js.map +1 -0
- package/dist/core/cleanup/scheduler.d.ts +50 -0
- package/dist/core/cleanup/scheduler.js +120 -0
- package/dist/core/cleanup/scheduler.js.map +1 -0
- package/dist/core/cleanup/worker.d.ts +63 -0
- package/dist/core/cleanup/worker.js +191 -0
- package/dist/core/cleanup/worker.js.map +1 -0
- package/dist/core/daemon.d.ts +1 -0
- package/dist/core/daemon.js +18 -0
- package/dist/core/daemon.js.map +1 -1
- package/dist/core/heartbeat.d.ts +6 -1
- package/dist/core/heartbeat.js +44 -39
- package/dist/core/heartbeat.js.map +1 -1
- package/dist/core/issue-cache.d.ts +44 -0
- package/dist/core/issue-cache.js +75 -0
- package/dist/core/issue-cache.js.map +1 -0
- package/dist/core/registry.d.ts +1 -0
- package/dist/core/registry.js +1 -0
- package/dist/core/registry.js.map +1 -1
- package/dist/core/token-lifecycle.d.ts +81 -0
- package/dist/core/token-lifecycle.js +210 -0
- package/dist/core/token-lifecycle.js.map +1 -0
- package/dist/core/token-lifecycle.test.d.ts +10 -0
- package/dist/core/token-lifecycle.test.js +309 -0
- package/dist/core/token-lifecycle.test.js.map +1 -0
- package/package.json +11 -12
package/dist/core/heartbeat.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getTokenTimeRemaining, isTokenExpiringSoon } from "../utils/jwt.js";
|
|
2
|
-
|
|
2
|
+
import { TokenLifecycleManager } from "./token-lifecycle.js";
|
|
3
|
+
// Refresh token when less than 24 hours remain (legacy threshold kept for compatibility)
|
|
3
4
|
const TOKEN_REFRESH_THRESHOLD_MS = 24 * 60 * 60 * 1000;
|
|
4
5
|
export class Heartbeat {
|
|
5
6
|
config;
|
|
@@ -7,15 +8,46 @@ export class Heartbeat {
|
|
|
7
8
|
intervalId = null;
|
|
8
9
|
heartbeatCount = 0;
|
|
9
10
|
contextSaveFrequency;
|
|
11
|
+
lifecycle;
|
|
10
12
|
constructor(config) {
|
|
11
13
|
this.config = config;
|
|
12
14
|
this.currentToken = config.token;
|
|
13
15
|
this.contextSaveFrequency = config.contextSaveFrequency ?? 5;
|
|
16
|
+
this.lifecycle =
|
|
17
|
+
config.lifecycleManager ??
|
|
18
|
+
new TokenLifecycleManager({
|
|
19
|
+
hubUrl: config.url,
|
|
20
|
+
initialToken: config.token,
|
|
21
|
+
bootstrap: {
|
|
22
|
+
apiKey: config.apiKey,
|
|
23
|
+
agentId: config.agentId,
|
|
24
|
+
displayName: config.agentName,
|
|
25
|
+
// Use actual model — fixes #401 hardcoded "claude-sonnet-4" bug
|
|
26
|
+
model: config.model ?? "claude-sonnet-4-5",
|
|
27
|
+
workspace: config.workspace,
|
|
28
|
+
},
|
|
29
|
+
onTokenUpdate: (newToken, expiresAt) => {
|
|
30
|
+
this.currentToken = newToken;
|
|
31
|
+
console.log(`[Heartbeat] Token updated, expires ${expiresAt}`);
|
|
32
|
+
config.onTokenRefresh?.(newToken);
|
|
33
|
+
},
|
|
34
|
+
onEvent: (evt) => {
|
|
35
|
+
console.log(`[TokenLifecycle] ${evt.type}`, {
|
|
36
|
+
attempt: evt.attempt,
|
|
37
|
+
error: evt.error,
|
|
38
|
+
nextRetryMs: evt.nextRetryMs,
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
// 24h threshold to keep behaviour compatible with existing daemon
|
|
42
|
+
refreshThresholdMs: TOKEN_REFRESH_THRESHOLD_MS,
|
|
43
|
+
});
|
|
14
44
|
}
|
|
15
45
|
start() {
|
|
16
46
|
if (this.intervalId) {
|
|
17
47
|
return;
|
|
18
48
|
}
|
|
49
|
+
// Start token lifecycle manager
|
|
50
|
+
this.lifecycle.start();
|
|
19
51
|
// Send initial heartbeat
|
|
20
52
|
this.sendHeartbeat();
|
|
21
53
|
// Schedule recurring heartbeats
|
|
@@ -24,36 +56,37 @@ export class Heartbeat {
|
|
|
24
56
|
}, this.config.intervalMs);
|
|
25
57
|
}
|
|
26
58
|
stop() {
|
|
59
|
+
this.lifecycle.stop();
|
|
27
60
|
if (this.intervalId) {
|
|
28
61
|
clearInterval(this.intervalId);
|
|
29
62
|
this.intervalId = null;
|
|
30
63
|
}
|
|
31
64
|
}
|
|
32
65
|
getToken() {
|
|
33
|
-
return
|
|
66
|
+
// Always return the live token from lifecycle manager
|
|
67
|
+
return this.lifecycle.getToken();
|
|
34
68
|
}
|
|
35
69
|
async sendHeartbeat() {
|
|
36
70
|
try {
|
|
37
|
-
//
|
|
38
|
-
if (isTokenExpiringSoon(this.
|
|
39
|
-
const remaining = getTokenTimeRemaining(this.
|
|
71
|
+
// Legacy inline check kept for immediate 401 recovery
|
|
72
|
+
if (isTokenExpiringSoon(this.lifecycle.getToken(), TOKEN_REFRESH_THRESHOLD_MS)) {
|
|
73
|
+
const remaining = getTokenTimeRemaining(this.lifecycle.getToken());
|
|
40
74
|
const hours = Math.floor(remaining / (1000 * 60 * 60));
|
|
41
|
-
console.log(`Token expiring in ${hours} hours,
|
|
42
|
-
|
|
75
|
+
console.log(`[Heartbeat] Token expiring in ${hours} hours, lifecycle manager notified`);
|
|
76
|
+
// Lifecycle manager handles the actual refresh
|
|
43
77
|
}
|
|
44
78
|
const response = await fetch(`${this.config.url}/api/v1/agents/heartbeat`, {
|
|
45
79
|
method: "POST",
|
|
46
80
|
headers: {
|
|
47
|
-
Authorization: `Bearer ${this.
|
|
81
|
+
Authorization: `Bearer ${this.lifecycle.getToken()}`,
|
|
48
82
|
"Content-Type": "application/json",
|
|
49
83
|
},
|
|
50
84
|
body: JSON.stringify({}),
|
|
51
85
|
});
|
|
52
86
|
if (!response.ok) {
|
|
53
|
-
// If unauthorized, try to refresh token
|
|
54
87
|
if (response.status === 401) {
|
|
55
|
-
console.log("Token rejected,
|
|
56
|
-
|
|
88
|
+
console.log("[Heartbeat] Token rejected (401), lifecycle manager will handle refresh");
|
|
89
|
+
// Lifecycle manager already running; nothing else needed here
|
|
57
90
|
return;
|
|
58
91
|
}
|
|
59
92
|
throw new Error(`Heartbeat failed: ${response.status}`);
|
|
@@ -68,33 +101,5 @@ export class Heartbeat {
|
|
|
68
101
|
this.config.onError?.(error);
|
|
69
102
|
}
|
|
70
103
|
}
|
|
71
|
-
async refreshToken() {
|
|
72
|
-
try {
|
|
73
|
-
const response = await fetch(`${this.config.url}/api/v1/agents/register`, {
|
|
74
|
-
method: "POST",
|
|
75
|
-
headers: {
|
|
76
|
-
"Content-Type": "application/json",
|
|
77
|
-
"x-agentmesh-secret": this.config.apiKey,
|
|
78
|
-
},
|
|
79
|
-
body: JSON.stringify({
|
|
80
|
-
agent_id: this.config.agentId,
|
|
81
|
-
workspace: this.config.workspace,
|
|
82
|
-
display_name: this.config.agentName,
|
|
83
|
-
model: "claude-sonnet-4",
|
|
84
|
-
}),
|
|
85
|
-
});
|
|
86
|
-
if (!response.ok) {
|
|
87
|
-
throw new Error(`Token refresh failed: ${response.status}`);
|
|
88
|
-
}
|
|
89
|
-
const data = (await response.json());
|
|
90
|
-
this.currentToken = data.token;
|
|
91
|
-
console.log("Token refreshed successfully");
|
|
92
|
-
this.config.onTokenRefresh?.(data.token);
|
|
93
|
-
}
|
|
94
|
-
catch (error) {
|
|
95
|
-
console.error("Failed to refresh token:", error.message);
|
|
96
|
-
this.config.onError?.(error);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
104
|
}
|
|
100
105
|
//# sourceMappingURL=heartbeat.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../src/core/heartbeat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../src/core/heartbeat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue Cache - Local storage for offline support
|
|
3
|
+
*/
|
|
4
|
+
export interface Issue {
|
|
5
|
+
issue_id: string;
|
|
6
|
+
workspace_id: string;
|
|
7
|
+
project_id: string | null;
|
|
8
|
+
title: string;
|
|
9
|
+
description: string | null;
|
|
10
|
+
type: string;
|
|
11
|
+
priority: string;
|
|
12
|
+
status: string;
|
|
13
|
+
assignee_agent_id: string | null;
|
|
14
|
+
assignee_user_id: string | null;
|
|
15
|
+
external_provider: string | null;
|
|
16
|
+
external_ref: string | null;
|
|
17
|
+
external_url: string | null;
|
|
18
|
+
parent_issue_id: string | null;
|
|
19
|
+
labels: string[];
|
|
20
|
+
metadata: Record<string, unknown>;
|
|
21
|
+
created_at: string;
|
|
22
|
+
updated_at: string;
|
|
23
|
+
synced_at: string | null;
|
|
24
|
+
}
|
|
25
|
+
export interface PendingChange {
|
|
26
|
+
action: "create" | "update" | "delete";
|
|
27
|
+
issueId?: string;
|
|
28
|
+
data?: Partial<Issue>;
|
|
29
|
+
queuedAt: string;
|
|
30
|
+
}
|
|
31
|
+
export interface IssueCache {
|
|
32
|
+
workspace: string;
|
|
33
|
+
lastSync: string | null;
|
|
34
|
+
issues: Issue[];
|
|
35
|
+
pendingChanges: PendingChange[];
|
|
36
|
+
}
|
|
37
|
+
export declare function loadCache(workspace: string): IssueCache;
|
|
38
|
+
export declare function saveCache(cache: IssueCache): void;
|
|
39
|
+
export declare function updateCacheIssues(workspace: string, issues: Issue[]): void;
|
|
40
|
+
export declare function getCachedIssue(workspace: string, issueId: string): Issue | null;
|
|
41
|
+
export declare function queueChange(workspace: string, change: PendingChange): void;
|
|
42
|
+
export declare function clearPendingChanges(workspace: string): void;
|
|
43
|
+
export declare function hasPendingChanges(workspace: string): boolean;
|
|
44
|
+
export declare function getLastSyncTime(workspace: string): string | null;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Issue Cache - Local storage for offline support
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
function getCacheDir() {
|
|
8
|
+
return join(homedir(), ".agentmesh", "cache");
|
|
9
|
+
}
|
|
10
|
+
function getCachePath(workspace) {
|
|
11
|
+
return join(getCacheDir(), `issues-${workspace}.json`);
|
|
12
|
+
}
|
|
13
|
+
function ensureCacheDir() {
|
|
14
|
+
const dir = getCacheDir();
|
|
15
|
+
if (!existsSync(dir)) {
|
|
16
|
+
mkdirSync(dir, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function loadCache(workspace) {
|
|
20
|
+
const path = getCachePath(workspace);
|
|
21
|
+
if (!existsSync(path)) {
|
|
22
|
+
return {
|
|
23
|
+
workspace,
|
|
24
|
+
lastSync: null,
|
|
25
|
+
issues: [],
|
|
26
|
+
pendingChanges: [],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const data = readFileSync(path, "utf-8");
|
|
31
|
+
return JSON.parse(data);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return {
|
|
35
|
+
workspace,
|
|
36
|
+
lastSync: null,
|
|
37
|
+
issues: [],
|
|
38
|
+
pendingChanges: [],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function saveCache(cache) {
|
|
43
|
+
ensureCacheDir();
|
|
44
|
+
const path = getCachePath(cache.workspace);
|
|
45
|
+
writeFileSync(path, JSON.stringify(cache, null, 2));
|
|
46
|
+
}
|
|
47
|
+
export function updateCacheIssues(workspace, issues) {
|
|
48
|
+
const cache = loadCache(workspace);
|
|
49
|
+
cache.issues = issues;
|
|
50
|
+
cache.lastSync = new Date().toISOString();
|
|
51
|
+
saveCache(cache);
|
|
52
|
+
}
|
|
53
|
+
export function getCachedIssue(workspace, issueId) {
|
|
54
|
+
const cache = loadCache(workspace);
|
|
55
|
+
return cache.issues.find((i) => i.issue_id === issueId) || null;
|
|
56
|
+
}
|
|
57
|
+
export function queueChange(workspace, change) {
|
|
58
|
+
const cache = loadCache(workspace);
|
|
59
|
+
cache.pendingChanges.push(change);
|
|
60
|
+
saveCache(cache);
|
|
61
|
+
}
|
|
62
|
+
export function clearPendingChanges(workspace) {
|
|
63
|
+
const cache = loadCache(workspace);
|
|
64
|
+
cache.pendingChanges = [];
|
|
65
|
+
saveCache(cache);
|
|
66
|
+
}
|
|
67
|
+
export function hasPendingChanges(workspace) {
|
|
68
|
+
const cache = loadCache(workspace);
|
|
69
|
+
return cache.pendingChanges.length > 0;
|
|
70
|
+
}
|
|
71
|
+
export function getLastSyncTime(workspace) {
|
|
72
|
+
const cache = loadCache(workspace);
|
|
73
|
+
return cache.lastSync;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=issue-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"issue-cache.js","sourceRoot":"","sources":["../../src/core/issue-cache.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAsCjC,SAAS,WAAW;IAClB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,YAAY,CAAC,SAAiB;IACrC,OAAO,IAAI,CAAC,WAAW,EAAE,EAAE,UAAU,SAAS,OAAO,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,cAAc;IACrB,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;IAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,SAAiB;IACzC,MAAM,IAAI,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAErC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO;YACL,SAAS;YACT,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,EAAE;YACV,cAAc,EAAE,EAAE;SACnB,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,SAAS;YACT,QAAQ,EAAE,IAAI;YACd,MAAM,EAAE,EAAE;YACV,cAAc,EAAE,EAAE;SACnB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAiB;IACzC,cAAc,EAAE,CAAC;IACjB,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC3C,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,SAAiB,EAAE,MAAe;IAClE,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,KAAK,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,SAAS,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,OAAe;IAC/D,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,MAAqB;IAClE,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClC,SAAS,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;IAC1B,SAAS,CAAC,KAAK,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IACjD,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,SAAiB;IAC/C,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,OAAO,KAAK,CAAC,QAAQ,CAAC;AACxB,CAAC"}
|
package/dist/core/registry.d.ts
CHANGED
package/dist/core/registry.js
CHANGED
|
@@ -14,6 +14,7 @@ export async function registerAgent(options) {
|
|
|
14
14
|
capabilities: options.capabilities || ["coding", "review", "debugging"],
|
|
15
15
|
workspace: options.workspace,
|
|
16
16
|
restore_context: options.restoreContext ?? false,
|
|
17
|
+
...(options.agentType ? { agent_type: options.agentType } : {}),
|
|
17
18
|
}),
|
|
18
19
|
});
|
|
19
20
|
if (!response.ok) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenLifecycleManager — #401 + #402
|
|
3
|
+
*
|
|
4
|
+
* Handles automatic token refresh with:
|
|
5
|
+
* - Expiry-aware scheduling (refresh at T-refreshThresholdMs before expiry)
|
|
6
|
+
* - Exponential backoff on failure (base 5s, max 5min, jitter ±20%)
|
|
7
|
+
* - Circuit-breaker: after maxConsecutiveFailures, switches to bootstrap
|
|
8
|
+
* re-register fallback (#402)
|
|
9
|
+
* - Re-register rate-limit guard: at most 1 re-register per minReregisterIntervalMs
|
|
10
|
+
* (default 10min) to prevent loops
|
|
11
|
+
* - Observable: emits structured lifecycle events via onEvent callback
|
|
12
|
+
*/
|
|
13
|
+
export type LifecycleEventType = "refresh_scheduled" | "refresh_attempt" | "refresh_success" | "refresh_failure" | "circuit_open" | "reregister_attempt" | "reregister_success" | "reregister_failure" | "reregister_rate_limited" | "token_expired_hard";
|
|
14
|
+
export interface LifecycleEvent {
|
|
15
|
+
type: LifecycleEventType;
|
|
16
|
+
agentId: string;
|
|
17
|
+
timestamp: string;
|
|
18
|
+
attempt?: number;
|
|
19
|
+
nextRetryMs?: number;
|
|
20
|
+
expiresAt?: string;
|
|
21
|
+
error?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface BootstrapCredentials {
|
|
24
|
+
/** The agentmesh shared secret used to re-register */
|
|
25
|
+
apiKey: string;
|
|
26
|
+
agentId: string;
|
|
27
|
+
displayName: string;
|
|
28
|
+
model: string;
|
|
29
|
+
workspace: string;
|
|
30
|
+
}
|
|
31
|
+
export interface TokenLifecycleConfig {
|
|
32
|
+
/** Hub base URL, e.g. "https://agentmeshhq.dev" */
|
|
33
|
+
hubUrl: string;
|
|
34
|
+
/** Initial token */
|
|
35
|
+
initialToken: string;
|
|
36
|
+
/** Bootstrap credentials for re-register fallback (#402) */
|
|
37
|
+
bootstrap: BootstrapCredentials;
|
|
38
|
+
/** Called whenever a new token is obtained (refresh or re-register) */
|
|
39
|
+
onTokenUpdate: (token: string, expiresAt: string) => void;
|
|
40
|
+
/** Optional structured event sink */
|
|
41
|
+
onEvent?: (event: LifecycleEvent) => void;
|
|
42
|
+
/** Refresh this many ms before expiry (default: 5 min) */
|
|
43
|
+
refreshThresholdMs?: number;
|
|
44
|
+
/** How often to check if refresh is needed (default: 60s) */
|
|
45
|
+
checkIntervalMs?: number;
|
|
46
|
+
/** Backoff base delay ms (default: 5000) */
|
|
47
|
+
backoffBaseMs?: number;
|
|
48
|
+
/** Max backoff delay ms (default: 300_000 = 5min) */
|
|
49
|
+
backoffMaxMs?: number;
|
|
50
|
+
/** Max consecutive refresh failures before opening circuit (default: 5) */
|
|
51
|
+
maxConsecutiveFailures?: number;
|
|
52
|
+
/** Minimum ms between re-register attempts (default: 10min) */
|
|
53
|
+
minReregisterIntervalMs?: number;
|
|
54
|
+
/** Fetch implementation (injectable for tests) */
|
|
55
|
+
fetch?: typeof globalThis.fetch;
|
|
56
|
+
}
|
|
57
|
+
export declare class TokenLifecycleManager {
|
|
58
|
+
private token;
|
|
59
|
+
private config;
|
|
60
|
+
private checkTimer;
|
|
61
|
+
private consecutiveFailures;
|
|
62
|
+
private circuitOpen;
|
|
63
|
+
private lastReregisterAttemptMs;
|
|
64
|
+
private stopped;
|
|
65
|
+
constructor(config: TokenLifecycleConfig);
|
|
66
|
+
/** Start the lifecycle check loop. */
|
|
67
|
+
start(): void;
|
|
68
|
+
/** Stop the lifecycle check loop. */
|
|
69
|
+
stop(): void;
|
|
70
|
+
/** Return the current live token. */
|
|
71
|
+
getToken(): string;
|
|
72
|
+
private scheduleNextCheck;
|
|
73
|
+
private runCheck;
|
|
74
|
+
private attemptRefresh;
|
|
75
|
+
private attemptReregister;
|
|
76
|
+
private acceptNewToken;
|
|
77
|
+
private openCircuit;
|
|
78
|
+
private calcBackoff;
|
|
79
|
+
private emit;
|
|
80
|
+
private sleep;
|
|
81
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenLifecycleManager — #401 + #402
|
|
3
|
+
*
|
|
4
|
+
* Handles automatic token refresh with:
|
|
5
|
+
* - Expiry-aware scheduling (refresh at T-refreshThresholdMs before expiry)
|
|
6
|
+
* - Exponential backoff on failure (base 5s, max 5min, jitter ±20%)
|
|
7
|
+
* - Circuit-breaker: after maxConsecutiveFailures, switches to bootstrap
|
|
8
|
+
* re-register fallback (#402)
|
|
9
|
+
* - Re-register rate-limit guard: at most 1 re-register per minReregisterIntervalMs
|
|
10
|
+
* (default 10min) to prevent loops
|
|
11
|
+
* - Observable: emits structured lifecycle events via onEvent callback
|
|
12
|
+
*/
|
|
13
|
+
import { getTokenExpiry, isTokenExpiringSoon } from "../utils/jwt.js";
|
|
14
|
+
export class TokenLifecycleManager {
|
|
15
|
+
token;
|
|
16
|
+
config;
|
|
17
|
+
checkTimer = null;
|
|
18
|
+
consecutiveFailures = 0;
|
|
19
|
+
circuitOpen = false;
|
|
20
|
+
lastReregisterAttemptMs = 0;
|
|
21
|
+
stopped = false;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.token = config.initialToken;
|
|
24
|
+
this.config = {
|
|
25
|
+
hubUrl: config.hubUrl,
|
|
26
|
+
initialToken: config.initialToken,
|
|
27
|
+
bootstrap: config.bootstrap,
|
|
28
|
+
onTokenUpdate: config.onTokenUpdate,
|
|
29
|
+
onEvent: config.onEvent,
|
|
30
|
+
refreshThresholdMs: config.refreshThresholdMs ?? 5 * 60 * 1000,
|
|
31
|
+
checkIntervalMs: config.checkIntervalMs ?? 60 * 1000,
|
|
32
|
+
backoffBaseMs: config.backoffBaseMs ?? 5_000,
|
|
33
|
+
backoffMaxMs: config.backoffMaxMs ?? 300_000,
|
|
34
|
+
maxConsecutiveFailures: config.maxConsecutiveFailures ?? 5,
|
|
35
|
+
minReregisterIntervalMs: config.minReregisterIntervalMs ?? 10 * 60 * 1000,
|
|
36
|
+
fetch: config.fetch ?? globalThis.fetch,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** Start the lifecycle check loop. */
|
|
40
|
+
start() {
|
|
41
|
+
if (this.checkTimer)
|
|
42
|
+
return;
|
|
43
|
+
this.stopped = false;
|
|
44
|
+
this.scheduleNextCheck(0);
|
|
45
|
+
}
|
|
46
|
+
/** Stop the lifecycle check loop. */
|
|
47
|
+
stop() {
|
|
48
|
+
this.stopped = true;
|
|
49
|
+
if (this.checkTimer) {
|
|
50
|
+
clearTimeout(this.checkTimer);
|
|
51
|
+
this.checkTimer = null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** Return the current live token. */
|
|
55
|
+
getToken() {
|
|
56
|
+
return this.token;
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Internal scheduling
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
scheduleNextCheck(delayMs) {
|
|
62
|
+
if (this.stopped)
|
|
63
|
+
return;
|
|
64
|
+
this.checkTimer = setTimeout(() => {
|
|
65
|
+
this.checkTimer = null;
|
|
66
|
+
void this.runCheck();
|
|
67
|
+
}, delayMs);
|
|
68
|
+
}
|
|
69
|
+
async runCheck() {
|
|
70
|
+
if (this.stopped)
|
|
71
|
+
return;
|
|
72
|
+
if (isTokenExpiringSoon(this.token, this.config.refreshThresholdMs)) {
|
|
73
|
+
const expiry = getTokenExpiry(this.token);
|
|
74
|
+
this.emit({
|
|
75
|
+
type: "refresh_scheduled",
|
|
76
|
+
expiresAt: expiry?.toISOString(),
|
|
77
|
+
});
|
|
78
|
+
await this.attemptRefresh();
|
|
79
|
+
}
|
|
80
|
+
// Schedule next check unless stopped
|
|
81
|
+
this.scheduleNextCheck(this.config.checkIntervalMs);
|
|
82
|
+
}
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// Refresh path (#401)
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
async attemptRefresh(attempt = 1) {
|
|
87
|
+
if (this.circuitOpen) {
|
|
88
|
+
// Circuit is open — go straight to bootstrap fallback (#402)
|
|
89
|
+
await this.attemptReregister();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
this.emit({ type: "refresh_attempt", attempt });
|
|
93
|
+
try {
|
|
94
|
+
const resp = await this.config.fetch(`${this.config.hubUrl}/api/v1/agents/token/refresh`, {
|
|
95
|
+
method: "POST",
|
|
96
|
+
headers: {
|
|
97
|
+
Authorization: `Bearer ${this.token}`,
|
|
98
|
+
"Content-Type": "application/json",
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
if (resp.status === 401 || resp.status === 403) {
|
|
102
|
+
// Token already invalid — skip retry, go directly to re-register
|
|
103
|
+
this.emit({ type: "refresh_failure", attempt, error: `HTTP ${resp.status}` });
|
|
104
|
+
this.openCircuit();
|
|
105
|
+
await this.attemptReregister();
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (!resp.ok) {
|
|
109
|
+
throw new Error(`HTTP ${resp.status}`);
|
|
110
|
+
}
|
|
111
|
+
const data = (await resp.json());
|
|
112
|
+
this.acceptNewToken(data.token, data.expires_at, "refresh_success", attempt);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
116
|
+
this.consecutiveFailures++;
|
|
117
|
+
this.emit({ type: "refresh_failure", attempt, error });
|
|
118
|
+
if (this.consecutiveFailures >= this.config.maxConsecutiveFailures) {
|
|
119
|
+
this.openCircuit();
|
|
120
|
+
await this.attemptReregister();
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
// Exponential backoff with ±20% jitter
|
|
124
|
+
const backoff = this.calcBackoff(attempt);
|
|
125
|
+
this.emit({ type: "refresh_failure", attempt, error, nextRetryMs: backoff });
|
|
126
|
+
// Retry with backoff (within the same "refresh cycle" — does not re-enter runCheck)
|
|
127
|
+
await this.sleep(backoff);
|
|
128
|
+
if (!this.stopped)
|
|
129
|
+
await this.attemptRefresh(attempt + 1);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Bootstrap re-register fallback (#402)
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
async attemptReregister() {
|
|
136
|
+
const now = Date.now();
|
|
137
|
+
const sinceLastMs = now - this.lastReregisterAttemptMs;
|
|
138
|
+
if (this.lastReregisterAttemptMs > 0 && sinceLastMs < this.config.minReregisterIntervalMs) {
|
|
139
|
+
// Rate-limit guard — prevent re-register loops
|
|
140
|
+
this.emit({
|
|
141
|
+
type: "reregister_rate_limited",
|
|
142
|
+
nextRetryMs: this.config.minReregisterIntervalMs - sinceLastMs,
|
|
143
|
+
});
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
this.lastReregisterAttemptMs = now;
|
|
147
|
+
this.emit({ type: "reregister_attempt" });
|
|
148
|
+
try {
|
|
149
|
+
const { bootstrap } = this.config;
|
|
150
|
+
const resp = await this.config.fetch(`${this.config.hubUrl}/api/v1/agents/register`, {
|
|
151
|
+
method: "POST",
|
|
152
|
+
headers: {
|
|
153
|
+
"Content-Type": "application/json",
|
|
154
|
+
"x-agentmesh-secret": bootstrap.apiKey,
|
|
155
|
+
},
|
|
156
|
+
body: JSON.stringify({
|
|
157
|
+
agent_id: bootstrap.agentId,
|
|
158
|
+
workspace: bootstrap.workspace,
|
|
159
|
+
display_name: bootstrap.displayName,
|
|
160
|
+
model: bootstrap.model,
|
|
161
|
+
}),
|
|
162
|
+
});
|
|
163
|
+
if (!resp.ok) {
|
|
164
|
+
throw new Error(`HTTP ${resp.status}`);
|
|
165
|
+
}
|
|
166
|
+
const data = (await resp.json());
|
|
167
|
+
// Reset circuit on successful re-register
|
|
168
|
+
this.consecutiveFailures = 0;
|
|
169
|
+
this.circuitOpen = false;
|
|
170
|
+
this.acceptNewToken(data.token, data.expires_at, "reregister_success");
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
174
|
+
this.emit({ type: "reregister_failure", error });
|
|
175
|
+
// After re-register failure we do NOT retry immediately — the rate-limit
|
|
176
|
+
// guard + next check cycle will handle it.
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// Helpers
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
acceptNewToken(token, expiresAt, eventType, attempt) {
|
|
183
|
+
this.token = token;
|
|
184
|
+
this.consecutiveFailures = 0;
|
|
185
|
+
this.circuitOpen = false;
|
|
186
|
+
this.emit({ type: eventType, attempt, expiresAt });
|
|
187
|
+
this.config.onTokenUpdate(token, expiresAt);
|
|
188
|
+
}
|
|
189
|
+
openCircuit() {
|
|
190
|
+
this.circuitOpen = true;
|
|
191
|
+
this.emit({ type: "circuit_open" });
|
|
192
|
+
}
|
|
193
|
+
calcBackoff(attempt) {
|
|
194
|
+
const base = Math.min(this.config.backoffBaseMs * 2 ** (attempt - 1), this.config.backoffMaxMs);
|
|
195
|
+
// ±20% jitter
|
|
196
|
+
const jitter = base * 0.2 * (Math.random() * 2 - 1);
|
|
197
|
+
return Math.round(base + jitter);
|
|
198
|
+
}
|
|
199
|
+
emit(partial) {
|
|
200
|
+
this.config.onEvent?.({
|
|
201
|
+
agentId: this.config.bootstrap.agentId,
|
|
202
|
+
timestamp: new Date().toISOString(),
|
|
203
|
+
...partial,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
sleep(ms) {
|
|
207
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=token-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-lifecycle.js","sourceRoot":"","sources":["../../src/core/token-lifecycle.ts"],"names":[],"mappings":"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"}
|