@holon-run/agentinbox 1.0.0-beta.5 → 1.0.1
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/README.md +5 -4
- package/dist/src/cli.js +26 -3
- package/dist/src/http.js +48 -3
- package/dist/src/service.js +112 -16
- package/dist/src/store.js +22 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,18 +55,19 @@ manually or relying on the agent runtime to expose its own notification API.
|
|
|
55
55
|
|
|
56
56
|
## Status
|
|
57
57
|
|
|
58
|
-
`AgentInbox` is
|
|
58
|
+
`AgentInbox` is on the stable v1 release line.
|
|
59
59
|
|
|
60
60
|
- the local control plane, daemon model, inbox model, and activation targets
|
|
61
61
|
are implemented
|
|
62
62
|
- GitHub repo, GitHub repo CI, Feishu bot, and local event ingress source
|
|
63
63
|
adapters are implemented
|
|
64
|
-
- filtering and source
|
|
64
|
+
- filtering and source breadth are still evolving
|
|
65
65
|
- first-run onboarding is currently skill-first rather than wizard-first
|
|
66
66
|
|
|
67
|
-
## v1
|
|
67
|
+
## v1 Upgrade Notes
|
|
68
68
|
|
|
69
|
-
`v1.0.0-beta.0` was the first release on the final v1 storage and API boundary
|
|
69
|
+
`v1.0.0-beta.0` was the first release on the final v1 storage and API boundary,
|
|
70
|
+
and `1.0.0` keeps that same boundary.
|
|
70
71
|
|
|
71
72
|
- pre-v1 local databases are archived and replaced with a fresh v1 database
|
|
72
73
|
- old local state is not imported into the new v1 database
|
package/dist/src/cli.js
CHANGED
|
@@ -355,9 +355,31 @@ async function main() {
|
|
|
355
355
|
return;
|
|
356
356
|
}
|
|
357
357
|
if (command === "agent" && normalized[1] === "register") {
|
|
358
|
+
const agentId = takeFlagValue(normalized, "--agent-id") ?? undefined;
|
|
359
|
+
const notifyLeaseMs = parseOptionalNumber(takeFlagValue(normalized, "--notify-lease-ms")) ?? undefined;
|
|
360
|
+
const minUnackedItems = parseOptionalNumber(takeFlagValue(normalized, "--min-unacked-items")) ?? undefined;
|
|
361
|
+
const webhookUrl = takeFlagValue(normalized, "--webhook-url");
|
|
362
|
+
if (webhookUrl) {
|
|
363
|
+
if (!agentId) {
|
|
364
|
+
throw new Error("usage: agentinbox agent register --agent-id ID --webhook-url URL [--webhook-activation-mode MODE] [--webhook-notify-lease-ms N] [--webhook-min-unacked-items N]");
|
|
365
|
+
}
|
|
366
|
+
const webhookNotifyLeaseMs = parseOptionalNumber(takeFlagValue(normalized, "--webhook-notify-lease-ms")) ?? notifyLeaseMs;
|
|
367
|
+
const webhookMinUnackedItems = parseOptionalNumber(takeFlagValue(normalized, "--webhook-min-unacked-items")) ?? minUnackedItems;
|
|
368
|
+
await printRemote(client, "/agents", {
|
|
369
|
+
agentId,
|
|
370
|
+
forceRebind: normalized.includes("--force-rebind"),
|
|
371
|
+
webhook: {
|
|
372
|
+
url: webhookUrl,
|
|
373
|
+
activationMode: takeFlagValue(normalized, "--webhook-activation-mode") ?? undefined,
|
|
374
|
+
notifyLeaseMs: webhookNotifyLeaseMs,
|
|
375
|
+
minUnackedItems: webhookMinUnackedItems,
|
|
376
|
+
},
|
|
377
|
+
});
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
358
380
|
const detected = (0, terminal_1.detectTerminalContext)(process.env);
|
|
359
381
|
await printRemote(client, "/agents", {
|
|
360
|
-
agentId
|
|
382
|
+
agentId,
|
|
361
383
|
forceRebind: normalized.includes("--force-rebind"),
|
|
362
384
|
backend: detected.backend,
|
|
363
385
|
runtimeKind: detected.runtimeKind,
|
|
@@ -367,8 +389,8 @@ async function main() {
|
|
|
367
389
|
tty: detected.tty ?? undefined,
|
|
368
390
|
termProgram: detected.termProgram ?? undefined,
|
|
369
391
|
itermSessionId: detected.itermSessionId ?? undefined,
|
|
370
|
-
notifyLeaseMs
|
|
371
|
-
minUnackedItems
|
|
392
|
+
notifyLeaseMs,
|
|
393
|
+
minUnackedItems,
|
|
372
394
|
});
|
|
373
395
|
return;
|
|
374
396
|
}
|
|
@@ -1297,6 +1319,7 @@ Usage:
|
|
|
1297
1319
|
|
|
1298
1320
|
Usage:
|
|
1299
1321
|
agentinbox agent register [--agent-id ID] [--force-rebind] [--notify-lease-ms N] [--min-unacked-items N]
|
|
1322
|
+
agentinbox agent register --agent-id ID --webhook-url URL [--webhook-activation-mode MODE] [--webhook-notify-lease-ms N] [--webhook-min-unacked-items N]
|
|
1300
1323
|
agentinbox agent list
|
|
1301
1324
|
agentinbox agent current
|
|
1302
1325
|
agentinbox agent show <agentId>
|
package/dist/src/http.js
CHANGED
|
@@ -772,11 +772,34 @@ function buildFastifyServer(service) {
|
|
|
772
772
|
body: {
|
|
773
773
|
type: "object",
|
|
774
774
|
additionalProperties: false,
|
|
775
|
-
|
|
775
|
+
oneOf: [
|
|
776
|
+
{
|
|
777
|
+
required: ["backend"],
|
|
778
|
+
properties: {
|
|
779
|
+
backend: { type: "string", enum: ["tmux", "iterm2"] },
|
|
780
|
+
},
|
|
781
|
+
},
|
|
782
|
+
{
|
|
783
|
+
required: ["agentId", "webhook"],
|
|
784
|
+
properties: {
|
|
785
|
+
webhook: {
|
|
786
|
+
type: "object",
|
|
787
|
+
additionalProperties: false,
|
|
788
|
+
required: ["url"],
|
|
789
|
+
properties: {
|
|
790
|
+
url: { type: "string", minLength: 1 },
|
|
791
|
+
activationMode: { type: "string", enum: ["activation_only", "activation_with_items"] },
|
|
792
|
+
notifyLeaseMs: { type: "integer", minimum: 1 },
|
|
793
|
+
minUnackedItems: { type: "integer", minimum: 1 },
|
|
794
|
+
},
|
|
795
|
+
},
|
|
796
|
+
},
|
|
797
|
+
},
|
|
798
|
+
],
|
|
776
799
|
properties: {
|
|
777
800
|
agentId: { type: "string" },
|
|
778
801
|
forceRebind: { type: "boolean" },
|
|
779
|
-
backend: { type: "string",
|
|
802
|
+
backend: { type: "string", enum: ["tmux", "iterm2"] },
|
|
780
803
|
runtimeKind: { type: "string" },
|
|
781
804
|
runtimeSessionId: { type: "string" },
|
|
782
805
|
runtimePid: { type: "integer", minimum: 1 },
|
|
@@ -786,6 +809,17 @@ function buildFastifyServer(service) {
|
|
|
786
809
|
itermSessionId: { type: "string" },
|
|
787
810
|
notifyLeaseMs: { type: "integer", minimum: 1 },
|
|
788
811
|
minUnackedItems: { type: "integer", minimum: 1 },
|
|
812
|
+
webhook: {
|
|
813
|
+
type: "object",
|
|
814
|
+
additionalProperties: false,
|
|
815
|
+
required: ["url"],
|
|
816
|
+
properties: {
|
|
817
|
+
url: { type: "string", minLength: 1 },
|
|
818
|
+
activationMode: { type: "string", enum: ["activation_only", "activation_with_items"] },
|
|
819
|
+
notifyLeaseMs: { type: "integer", minimum: 1 },
|
|
820
|
+
minUnackedItems: { type: "integer", minimum: 1 },
|
|
821
|
+
},
|
|
822
|
+
},
|
|
789
823
|
},
|
|
790
824
|
},
|
|
791
825
|
response: {
|
|
@@ -795,10 +829,11 @@ function buildFastifyServer(service) {
|
|
|
795
829
|
},
|
|
796
830
|
}, async (request) => {
|
|
797
831
|
const body = request.body;
|
|
832
|
+
const webhookBody = body.webhook;
|
|
798
833
|
return service.registerAgent({
|
|
799
834
|
agentId: optionalString(body.agentId) ?? null,
|
|
800
835
|
forceRebind: body.forceRebind === true,
|
|
801
|
-
backend:
|
|
836
|
+
backend: optionalString(body.backend),
|
|
802
837
|
runtimeKind: optionalString(body.runtimeKind),
|
|
803
838
|
runtimeSessionId: optionalString(body.runtimeSessionId),
|
|
804
839
|
runtimePid: typeof body.runtimePid === "number" ? body.runtimePid : null,
|
|
@@ -809,6 +844,14 @@ function buildFastifyServer(service) {
|
|
|
809
844
|
itermSessionId: optionalString(body.itermSessionId),
|
|
810
845
|
notifyLeaseMs: typeof body.notifyLeaseMs === "number" ? body.notifyLeaseMs : null,
|
|
811
846
|
minUnackedItems: typeof body.minUnackedItems === "number" ? body.minUnackedItems : null,
|
|
847
|
+
webhook: webhookBody
|
|
848
|
+
? {
|
|
849
|
+
url: String(webhookBody.url),
|
|
850
|
+
activationMode: optionalString(webhookBody.activationMode),
|
|
851
|
+
notifyLeaseMs: typeof webhookBody.notifyLeaseMs === "number" ? webhookBody.notifyLeaseMs : null,
|
|
852
|
+
minUnackedItems: typeof webhookBody.minUnackedItems === "number" ? webhookBody.minUnackedItems : null,
|
|
853
|
+
}
|
|
854
|
+
: null,
|
|
812
855
|
});
|
|
813
856
|
});
|
|
814
857
|
app.get("/agents/:agentId", {
|
|
@@ -1747,6 +1790,8 @@ function isBadRequestError(message) {
|
|
|
1747
1790
|
message.startsWith("expected boolean") ||
|
|
1748
1791
|
message.startsWith("expected integer") ||
|
|
1749
1792
|
message.startsWith("expected positive integer") ||
|
|
1793
|
+
message.startsWith("webhook agent registration requires") ||
|
|
1794
|
+
message.startsWith("agent registration requires either") ||
|
|
1750
1795
|
message.startsWith("notifyLeaseMs must be a positive integer") ||
|
|
1751
1796
|
message.startsWith("minUnackedItems must be a positive integer") ||
|
|
1752
1797
|
message.startsWith("invalid webhook activation target") ||
|
package/dist/src/service.js
CHANGED
|
@@ -516,18 +516,23 @@ class AgentInboxService {
|
|
|
516
516
|
registerAgent(input) {
|
|
517
517
|
validateNotifyLeaseMs(input.notifyLeaseMs);
|
|
518
518
|
validateMinUnackedItems(input.minUnackedItems);
|
|
519
|
-
|
|
519
|
+
validateRegisterAgentInput(input);
|
|
520
|
+
const webhookInput = input.webhook ?? null;
|
|
520
521
|
const runtimeKind = input.runtimeKind ?? "unknown";
|
|
521
|
-
const agentId =
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
522
|
+
const agentId = webhookInput
|
|
523
|
+
? input.agentId
|
|
524
|
+
: input.agentId ?? this.resolveAutoAgentId({
|
|
525
|
+
runtimeKind,
|
|
526
|
+
runtimeSessionId: input.runtimeSessionId ?? null,
|
|
527
|
+
backend: input.backend,
|
|
528
|
+
tmuxPaneId: input.tmuxPaneId ?? null,
|
|
529
|
+
itermSessionId: input.itermSessionId ?? null,
|
|
530
|
+
tty: input.tty ?? null,
|
|
531
|
+
});
|
|
529
532
|
const now = (0, util_1.nowIso)();
|
|
530
|
-
|
|
533
|
+
if (!webhookInput) {
|
|
534
|
+
this.handleAgentRegistrationConflicts(agentId, input);
|
|
535
|
+
}
|
|
531
536
|
const existingAgent = this.store.getAgent(agentId);
|
|
532
537
|
const agent = existingAgent
|
|
533
538
|
? this.store.updateAgent(agentId, {
|
|
@@ -552,11 +557,21 @@ class AgentInboxService {
|
|
|
552
557
|
this.store.insertAgent(created);
|
|
553
558
|
return created;
|
|
554
559
|
})();
|
|
555
|
-
|
|
560
|
+
let terminalTarget = null;
|
|
561
|
+
let webhookTarget = null;
|
|
562
|
+
if (webhookInput) {
|
|
563
|
+
webhookTarget = this.upsertWebhookActivationTarget(agent.agentId, webhookInput, now);
|
|
564
|
+
this.removeTerminalActivationTargets(agent.agentId);
|
|
565
|
+
}
|
|
566
|
+
else {
|
|
567
|
+
terminalTarget = this.upsertTerminalActivationTarget(agent.agentId, input, now);
|
|
568
|
+
}
|
|
556
569
|
const inbox = this.ensureInboxForAgent(agent.agentId);
|
|
557
570
|
return {
|
|
558
571
|
agent,
|
|
559
572
|
terminalTarget,
|
|
573
|
+
webhookTarget,
|
|
574
|
+
activationChannel: webhookTarget ? "webhook" : terminalTarget ? "terminal" : null,
|
|
560
575
|
inbox,
|
|
561
576
|
};
|
|
562
577
|
}
|
|
@@ -1197,7 +1212,7 @@ class AgentInboxService {
|
|
|
1197
1212
|
subscriptionIds: [],
|
|
1198
1213
|
});
|
|
1199
1214
|
this.notifyInboxWatchers(agentId, [entry]);
|
|
1200
|
-
const targets = this.
|
|
1215
|
+
const targets = this.listEffectiveActiveActivationTargets(agentId);
|
|
1201
1216
|
for (const target of targets) {
|
|
1202
1217
|
this.enqueueActivationTarget(target, {
|
|
1203
1218
|
agentId,
|
|
@@ -1466,7 +1481,7 @@ class AgentInboxService {
|
|
|
1466
1481
|
limit: DEFAULT_SUBSCRIPTION_POLL_LIMIT,
|
|
1467
1482
|
});
|
|
1468
1483
|
const inbox = this.ensureInboxForAgent(subscription.agentId);
|
|
1469
|
-
const targets = this.
|
|
1484
|
+
const targets = this.listEffectiveActiveActivationTargets(subscription.agentId);
|
|
1470
1485
|
let matched = 0;
|
|
1471
1486
|
let inboxItemsCreated = 0;
|
|
1472
1487
|
let lastProcessedOffset = null;
|
|
@@ -1796,6 +1811,12 @@ class AgentInboxService {
|
|
|
1796
1811
|
throw new Error("unable to derive a unique agentId from terminal context");
|
|
1797
1812
|
}
|
|
1798
1813
|
handleAgentRegistrationConflicts(agentId, input) {
|
|
1814
|
+
const activeWebhookTarget = this.store
|
|
1815
|
+
.listActivationTargetsForAgent(agentId)
|
|
1816
|
+
.find((target) => target.kind === "webhook" && target.status === "active");
|
|
1817
|
+
if (activeWebhookTarget) {
|
|
1818
|
+
throw new Error(`agent register conflict: agent ${agentId} already has active webhook target ${activeWebhookTarget.targetId}; terminal registration is disabled while webhook is active`);
|
|
1819
|
+
}
|
|
1799
1820
|
const currentTarget = findExistingTerminalActivationTarget(this.store, input);
|
|
1800
1821
|
if (currentTarget && currentTarget.agentId !== agentId) {
|
|
1801
1822
|
if (!input.forceRebind) {
|
|
@@ -1817,6 +1838,34 @@ class AgentInboxService {
|
|
|
1817
1838
|
}
|
|
1818
1839
|
}
|
|
1819
1840
|
}
|
|
1841
|
+
upsertWebhookActivationTarget(agentId, input, now) {
|
|
1842
|
+
validateNotifyLeaseMs(input.notifyLeaseMs);
|
|
1843
|
+
validateMinUnackedItems(input.minUnackedItems);
|
|
1844
|
+
const mode = normalizeWebhookActivationMode(input.activationMode);
|
|
1845
|
+
const targets = this.store
|
|
1846
|
+
.listActivationTargetsForAgent(agentId)
|
|
1847
|
+
.filter((target) => target.kind === "webhook");
|
|
1848
|
+
const matching = targets.find((target) => target.url === input.url);
|
|
1849
|
+
const existing = matching ?? targets[0] ?? null;
|
|
1850
|
+
if (existing) {
|
|
1851
|
+
const target = this.store.updateWebhookActivationTarget(existing.targetId, {
|
|
1852
|
+
url: input.url,
|
|
1853
|
+
mode,
|
|
1854
|
+
notifyLeaseMs: input.notifyLeaseMs ?? existing.notifyLeaseMs,
|
|
1855
|
+
minUnackedItems: input.minUnackedItems ?? existing.minUnackedItems ?? null,
|
|
1856
|
+
updatedAt: now,
|
|
1857
|
+
lastSeenAt: now,
|
|
1858
|
+
});
|
|
1859
|
+
for (const duplicate of targets) {
|
|
1860
|
+
if (duplicate.targetId !== target.targetId) {
|
|
1861
|
+
this.store.deleteActivationTarget(agentId, duplicate.targetId);
|
|
1862
|
+
}
|
|
1863
|
+
}
|
|
1864
|
+
this.markAgentActive(agentId);
|
|
1865
|
+
return target;
|
|
1866
|
+
}
|
|
1867
|
+
return this.addWebhookActivationTarget(agentId, input);
|
|
1868
|
+
}
|
|
1820
1869
|
upsertTerminalActivationTarget(agentId, input, now) {
|
|
1821
1870
|
const existing = findExistingTerminalActivationTarget(this.store, input);
|
|
1822
1871
|
if (existing) {
|
|
@@ -1872,6 +1921,21 @@ class AgentInboxService {
|
|
|
1872
1921
|
this.markAgentActive(agentId);
|
|
1873
1922
|
return target;
|
|
1874
1923
|
}
|
|
1924
|
+
removeTerminalActivationTargets(agentId) {
|
|
1925
|
+
const targets = this.store
|
|
1926
|
+
.listActivationTargetsForAgent(agentId)
|
|
1927
|
+
.filter((target) => target.kind === "terminal");
|
|
1928
|
+
for (const target of targets) {
|
|
1929
|
+
this.store.deleteActivationTarget(agentId, target.targetId);
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
listEffectiveActiveActivationTargets(agentId) {
|
|
1933
|
+
const targets = this.store.listActivationTargetsForAgent(agentId).filter((target) => target.status === "active");
|
|
1934
|
+
return effectiveActiveTargets(targets);
|
|
1935
|
+
}
|
|
1936
|
+
isEffectiveActiveTarget(agentId, targetId) {
|
|
1937
|
+
return this.listEffectiveActiveActivationTargets(agentId).some((target) => target.targetId === targetId);
|
|
1938
|
+
}
|
|
1875
1939
|
enqueueActivationTarget(target, input) {
|
|
1876
1940
|
const key = notificationBufferKey(target.agentId, target.targetId);
|
|
1877
1941
|
let buffer = this.notificationBuffers.get(key);
|
|
@@ -2108,6 +2172,10 @@ class AgentInboxService {
|
|
|
2108
2172
|
this.store.deleteActivationDispatchState(agentId, targetId);
|
|
2109
2173
|
return;
|
|
2110
2174
|
}
|
|
2175
|
+
if (!this.isEffectiveActiveTarget(agentId, targetId)) {
|
|
2176
|
+
this.store.deleteActivationDispatchState(agentId, targetId);
|
|
2177
|
+
return;
|
|
2178
|
+
}
|
|
2111
2179
|
const inbox = this.ensureInboxForAgent(agentId);
|
|
2112
2180
|
const unacked = this.store.listInboxEntries(inbox.inboxId, { includeAcked: false }).length;
|
|
2113
2181
|
if (unacked === 0) {
|
|
@@ -2181,6 +2249,15 @@ class AgentInboxService {
|
|
|
2181
2249
|
if (target.status === "offline") {
|
|
2182
2250
|
return "offline";
|
|
2183
2251
|
}
|
|
2252
|
+
if (!this.isEffectiveActiveTarget(input.agentId, input.targetId)) {
|
|
2253
|
+
this.logger.debug("activation.dispatch_suppressed", {
|
|
2254
|
+
agentId: input.agentId,
|
|
2255
|
+
targetId: target.targetId,
|
|
2256
|
+
reason: "non_effective_target",
|
|
2257
|
+
targetKind: target.kind,
|
|
2258
|
+
});
|
|
2259
|
+
return "suppressed";
|
|
2260
|
+
}
|
|
2184
2261
|
const state = this.store.getActivationDispatchState(input.agentId, input.targetId);
|
|
2185
2262
|
const inbox = this.ensureInboxForAgent(input.agentId);
|
|
2186
2263
|
const summary = summarizeActivation(inbox.inboxId, input.newItemCount, input.summary);
|
|
@@ -2781,7 +2858,7 @@ class AgentInboxService {
|
|
|
2781
2858
|
continue;
|
|
2782
2859
|
}
|
|
2783
2860
|
this.notifyInboxWatchers(inbox.ownerAgentId, [entry]);
|
|
2784
|
-
const targets = this.
|
|
2861
|
+
const targets = this.listEffectiveActiveActivationTargets(inbox.ownerAgentId);
|
|
2785
2862
|
for (const target of targets) {
|
|
2786
2863
|
this.enqueueActivationTarget(target, {
|
|
2787
2864
|
agentId: inbox.ownerAgentId,
|
|
@@ -3259,7 +3336,13 @@ class ActivationDispatcher {
|
|
|
3259
3336
|
}
|
|
3260
3337
|
}
|
|
3261
3338
|
exports.ActivationDispatcher = ActivationDispatcher;
|
|
3262
|
-
function
|
|
3339
|
+
function validateRegisterAgentInput(input) {
|
|
3340
|
+
if (input.webhook) {
|
|
3341
|
+
if (!input.agentId) {
|
|
3342
|
+
throw new Error("webhook agent registration requires agentId");
|
|
3343
|
+
}
|
|
3344
|
+
return;
|
|
3345
|
+
}
|
|
3263
3346
|
if (input.backend === "tmux") {
|
|
3264
3347
|
if (!input.tmuxPaneId) {
|
|
3265
3348
|
throw new Error("tmux agent registration requires tmuxPaneId");
|
|
@@ -3272,7 +3355,10 @@ function validateTerminalRegistration(input) {
|
|
|
3272
3355
|
}
|
|
3273
3356
|
return;
|
|
3274
3357
|
}
|
|
3275
|
-
|
|
3358
|
+
if (input.backend) {
|
|
3359
|
+
throw new Error(`unsupported terminal backend: ${input.backend}`);
|
|
3360
|
+
}
|
|
3361
|
+
throw new Error("agent registration requires either a terminal backend or webhook");
|
|
3276
3362
|
}
|
|
3277
3363
|
function validateNotifyLeaseMs(value) {
|
|
3278
3364
|
if (value == null) {
|
|
@@ -3360,6 +3446,9 @@ function normalizeWebhookActivationMode(mode) {
|
|
|
3360
3446
|
return resolved;
|
|
3361
3447
|
}
|
|
3362
3448
|
function findExistingTerminalActivationTarget(store, input) {
|
|
3449
|
+
if (!input.backend) {
|
|
3450
|
+
return null;
|
|
3451
|
+
}
|
|
3363
3452
|
if (input.runtimeSessionId) {
|
|
3364
3453
|
const target = store.getTerminalActivationTargetByRuntimeSession(input.runtimeKind ?? "unknown", input.runtimeSessionId);
|
|
3365
3454
|
if (target) {
|
|
@@ -3379,6 +3468,13 @@ function findExistingTerminalActivationTarget(store, input) {
|
|
|
3379
3468
|
}
|
|
3380
3469
|
return null;
|
|
3381
3470
|
}
|
|
3471
|
+
function effectiveActiveTargets(targets) {
|
|
3472
|
+
const activeWebhookTargets = targets.filter((target) => target.kind === "webhook" && target.status === "active");
|
|
3473
|
+
if (activeWebhookTargets.length > 0) {
|
|
3474
|
+
return activeWebhookTargets;
|
|
3475
|
+
}
|
|
3476
|
+
return targets.filter((target) => target.status === "active");
|
|
3477
|
+
}
|
|
3382
3478
|
function isSameTerminalIdentity(target, input) {
|
|
3383
3479
|
if (input.runtimeSessionId && target.runtimeKind === (input.runtimeKind ?? "unknown") && target.runtimeSessionId === input.runtimeSessionId) {
|
|
3384
3480
|
return true;
|
package/dist/src/store.js
CHANGED
|
@@ -777,6 +777,28 @@ class AgentInboxStore {
|
|
|
777
777
|
}
|
|
778
778
|
return target;
|
|
779
779
|
}
|
|
780
|
+
updateWebhookActivationTarget(targetId, input) {
|
|
781
|
+
this.db.run(`
|
|
782
|
+
update activation_targets
|
|
783
|
+
set kind = 'webhook', status = 'active', offline_since = null, last_error = null, consecutive_failures = 0,
|
|
784
|
+
mode = ?, notify_lease_ms = ?, min_unacked_items = ?, url = ?, updated_at = ?, last_seen_at = ?
|
|
785
|
+
where target_id = ? and kind = 'webhook'
|
|
786
|
+
`, [
|
|
787
|
+
input.mode,
|
|
788
|
+
input.notifyLeaseMs,
|
|
789
|
+
input.minUnackedItems,
|
|
790
|
+
input.url,
|
|
791
|
+
input.updatedAt,
|
|
792
|
+
input.lastSeenAt,
|
|
793
|
+
targetId,
|
|
794
|
+
]);
|
|
795
|
+
this.persist();
|
|
796
|
+
const target = this.getActivationTarget(targetId);
|
|
797
|
+
if (!target || target.kind !== "webhook") {
|
|
798
|
+
throw new Error(`unknown webhook activation target: ${targetId}`);
|
|
799
|
+
}
|
|
800
|
+
return target;
|
|
801
|
+
}
|
|
780
802
|
updateActivationTargetRuntime(targetId, input) {
|
|
781
803
|
const current = this.getActivationTarget(targetId);
|
|
782
804
|
if (!current) {
|