@holon-run/agentinbox 1.2.0 → 1.3.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/src/cli.js +28 -0
- package/dist/src/http.js +39 -0
- package/dist/src/service.js +23 -0
- package/dist/src/sources/feishu.js +2 -53
- package/package.json +1 -1
package/dist/src/cli.js
CHANGED
|
@@ -533,6 +533,27 @@ async function main() {
|
|
|
533
533
|
await printRemote(client, `/agents/${encodeURIComponent(agentId)}/targets/${encodeURIComponent(targetId)}/resume`, {});
|
|
534
534
|
return;
|
|
535
535
|
}
|
|
536
|
+
if (command === "agent" && normalized[1] === "target" && normalized[2] === "update") {
|
|
537
|
+
const [agentId, targetId] = normalized.slice(3, 5);
|
|
538
|
+
if (!agentId || !targetId) {
|
|
539
|
+
throw new Error("usage: agentinbox agent target update <agentId> <targetId> [--url URL] [--activation-mode MODE] [--notify-lease-ms N] [--min-unacked-items N]");
|
|
540
|
+
}
|
|
541
|
+
const body = {};
|
|
542
|
+
const url = takeFlagValue(normalized, "--url");
|
|
543
|
+
if (url)
|
|
544
|
+
body.url = url;
|
|
545
|
+
const activationMode = takeFlagValue(normalized, "--activation-mode");
|
|
546
|
+
if (activationMode)
|
|
547
|
+
body.activationMode = activationMode;
|
|
548
|
+
const notifyLeaseMs = takeFlagValue(normalized, "--notify-lease-ms");
|
|
549
|
+
if (notifyLeaseMs)
|
|
550
|
+
body.notifyLeaseMs = parseOptionalNumber(notifyLeaseMs);
|
|
551
|
+
const minUnackedItems = takeFlagValue(normalized, "--min-unacked-items");
|
|
552
|
+
if (minUnackedItems)
|
|
553
|
+
body.minUnackedItems = parseOptionalNumber(minUnackedItems);
|
|
554
|
+
await printRemote(client, `/agents/${encodeURIComponent(agentId)}/targets/${encodeURIComponent(targetId)}`, body, "PATCH");
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
536
557
|
if (command === "subscription" && normalized[1] === "add") {
|
|
537
558
|
const args = normalized.slice(2);
|
|
538
559
|
const positionals = positionalArgs(args, [
|
|
@@ -1154,11 +1175,17 @@ function clientArgsForCommand(args) {
|
|
|
1154
1175
|
if (isAgentTargetAddWebhookCommand(args)) {
|
|
1155
1176
|
return withoutFlagValues(args, "--url");
|
|
1156
1177
|
}
|
|
1178
|
+
if (isAgentTargetUpdateCommand(args)) {
|
|
1179
|
+
return withoutFlagValues(args, "--url");
|
|
1180
|
+
}
|
|
1157
1181
|
return args;
|
|
1158
1182
|
}
|
|
1159
1183
|
function isAgentTargetAddWebhookCommand(args) {
|
|
1160
1184
|
return args[0] === "agent" && args[1] === "target" && args[2] === "add" && args[3] === "webhook";
|
|
1161
1185
|
}
|
|
1186
|
+
function isAgentTargetUpdateCommand(args) {
|
|
1187
|
+
return args[0] === "agent" && args[1] === "target" && args[2] === "update";
|
|
1188
|
+
}
|
|
1162
1189
|
function withoutFlagValues(args, flag) {
|
|
1163
1190
|
const filtered = [];
|
|
1164
1191
|
for (let index = 0; index < args.length; index += 1) {
|
|
@@ -1514,6 +1541,7 @@ Usage:
|
|
|
1514
1541
|
agentinbox agent target list <agentId> [--limit N]
|
|
1515
1542
|
agentinbox agent target remove <agentId> <targetId>
|
|
1516
1543
|
agentinbox agent target resume <agentId> <targetId>
|
|
1544
|
+
agentinbox agent target update <agentId> <targetId> [--url URL] [--activation-mode MODE] [--notify-lease-ms N] [--min-unacked-items N]
|
|
1517
1545
|
`,
|
|
1518
1546
|
timer: `agentinbox timer
|
|
1519
1547
|
|
package/dist/src/http.js
CHANGED
|
@@ -1061,6 +1061,45 @@ function buildFastifyServer(service) {
|
|
|
1061
1061
|
minUnackedItems: body.minUnackedItems ?? null,
|
|
1062
1062
|
});
|
|
1063
1063
|
});
|
|
1064
|
+
app.patch("/agents/:agentId/targets/:targetId", {
|
|
1065
|
+
schema: {
|
|
1066
|
+
tags: ["agents"],
|
|
1067
|
+
params: {
|
|
1068
|
+
type: "object",
|
|
1069
|
+
required: ["agentId", "targetId"],
|
|
1070
|
+
properties: {
|
|
1071
|
+
agentId: { type: "string", minLength: 1 },
|
|
1072
|
+
targetId: { type: "string", minLength: 1 },
|
|
1073
|
+
},
|
|
1074
|
+
},
|
|
1075
|
+
body: {
|
|
1076
|
+
type: "object",
|
|
1077
|
+
additionalProperties: false,
|
|
1078
|
+
properties: {
|
|
1079
|
+
url: { type: "string" },
|
|
1080
|
+
activationMode: { type: "string" },
|
|
1081
|
+
notifyLeaseMs: { type: "integer", minimum: 1 },
|
|
1082
|
+
minUnackedItems: { type: "integer", minimum: 1 },
|
|
1083
|
+
},
|
|
1084
|
+
},
|
|
1085
|
+
response: {
|
|
1086
|
+
200: jsonObjectSchema,
|
|
1087
|
+
400: errorResponseSchema,
|
|
1088
|
+
},
|
|
1089
|
+
},
|
|
1090
|
+
}, async (request) => {
|
|
1091
|
+
const params = request.params;
|
|
1092
|
+
const body = request.body;
|
|
1093
|
+
if (!body.url && body.activationMode === undefined && body.notifyLeaseMs === undefined && body.minUnackedItems === undefined) {
|
|
1094
|
+
throw new Error("at least one of --url, --activation-mode, --notify-lease-ms, --min-unacked-items must be provided");
|
|
1095
|
+
}
|
|
1096
|
+
return service.updateWebhookActivationTarget(decodeURIComponent(params.agentId), decodeURIComponent(params.targetId), {
|
|
1097
|
+
url: body.url,
|
|
1098
|
+
activationMode: body.activationMode,
|
|
1099
|
+
notifyLeaseMs: body.notifyLeaseMs ?? null,
|
|
1100
|
+
minUnackedItems: body.minUnackedItems ?? null,
|
|
1101
|
+
});
|
|
1102
|
+
});
|
|
1064
1103
|
app.delete("/agents/:agentId/targets/:targetId", {
|
|
1065
1104
|
schema: {
|
|
1066
1105
|
tags: ["agents"],
|
package/dist/src/service.js
CHANGED
|
@@ -774,6 +774,29 @@ class AgentInboxService {
|
|
|
774
774
|
this.markAgentActive(agentId);
|
|
775
775
|
return target;
|
|
776
776
|
}
|
|
777
|
+
updateWebhookActivationTarget(agentId, targetId, input) {
|
|
778
|
+
this.getAgent(agentId);
|
|
779
|
+
const existing = this.getActivationTarget(targetId);
|
|
780
|
+
if (existing.agentId !== agentId) {
|
|
781
|
+
throw new Error(`activation target ${targetId} does not belong to agent ${agentId}`);
|
|
782
|
+
}
|
|
783
|
+
if (existing.kind !== "webhook") {
|
|
784
|
+
throw new Error(`activation target ${targetId} is not a webhook target`);
|
|
785
|
+
}
|
|
786
|
+
validateNotifyLeaseMs(input.notifyLeaseMs);
|
|
787
|
+
validateMinUnackedItems(input.minUnackedItems);
|
|
788
|
+
const mode = normalizeWebhookActivationMode(input.activationMode ?? existing.mode);
|
|
789
|
+
const now = (0, util_1.nowIso)();
|
|
790
|
+
const target = this.store.updateWebhookActivationTarget(targetId, {
|
|
791
|
+
url: input.url ?? existing.url,
|
|
792
|
+
mode,
|
|
793
|
+
notifyLeaseMs: input.notifyLeaseMs ?? existing.notifyLeaseMs,
|
|
794
|
+
minUnackedItems: input.minUnackedItems !== undefined ? input.minUnackedItems : existing.minUnackedItems ?? null,
|
|
795
|
+
updatedAt: now,
|
|
796
|
+
lastSeenAt: now,
|
|
797
|
+
});
|
|
798
|
+
return target;
|
|
799
|
+
}
|
|
777
800
|
listActivationTargets(agentId, limit) {
|
|
778
801
|
if (agentId) {
|
|
779
802
|
this.getAgent(agentId);
|
|
@@ -14,11 +14,9 @@ const node_child_process_1 = require("node:child_process");
|
|
|
14
14
|
const node_crypto_1 = require("node:crypto");
|
|
15
15
|
const node_fs_1 = require("node:fs");
|
|
16
16
|
const node_path_1 = require("node:path");
|
|
17
|
-
const node_os_1 = require("node:os");
|
|
18
17
|
const node_util_1 = require("node:util");
|
|
19
18
|
exports.FEISHU_OPENAPI_ENDPOINT = "https://open.feishu.cn/open-apis";
|
|
20
19
|
exports.FEISHU_IM_SCHEMA_URL = "https://raw.githubusercontent.com/holon-run/uxc/main/skills/feishu-openapi-skill/references/feishu-im.openapi.json";
|
|
21
|
-
const FEISHU_BOT_SCHEMA_FILE = (0, node_path_1.join)((0, node_os_1.tmpdir)(), "agentinbox-feishu-bot.openapi.json");
|
|
22
20
|
exports.DEFAULT_FEISHU_EVENT_TYPES = ["im.message.receive_v1"];
|
|
23
21
|
const DEFAULT_CONTEXT_BOUND_SECONDS = 7 * 24 * 60 * 60;
|
|
24
22
|
const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
|
|
@@ -131,10 +129,8 @@ class FeishuUxcClient {
|
|
|
131
129
|
operation: "get:/bot/v3/info",
|
|
132
130
|
payload: {},
|
|
133
131
|
options: {
|
|
134
|
-
auth: input.auth,
|
|
135
|
-
schema_url:
|
|
136
|
-
refresh_schema: true,
|
|
137
|
-
no_cache: true,
|
|
132
|
+
auth: input.auth ?? undefined,
|
|
133
|
+
schema_url: exports.FEISHU_IM_SCHEMA_URL,
|
|
138
134
|
},
|
|
139
135
|
});
|
|
140
136
|
const openId = findStringField(response.data, "open_id");
|
|
@@ -1873,50 +1869,3 @@ function asStringArray(value) {
|
|
|
1873
1869
|
.map((item) => asString(item))
|
|
1874
1870
|
.filter((item) => Boolean(item));
|
|
1875
1871
|
}
|
|
1876
|
-
function ensureFeishuBotSchemaFile() {
|
|
1877
|
-
const body = JSON.stringify(FEISHU_BOT_OPENAPI_SCHEMA);
|
|
1878
|
-
(0, node_fs_1.writeFileSync)(FEISHU_BOT_SCHEMA_FILE, body, "utf8");
|
|
1879
|
-
return FEISHU_BOT_SCHEMA_FILE;
|
|
1880
|
-
}
|
|
1881
|
-
const FEISHU_BOT_OPENAPI_SCHEMA = {
|
|
1882
|
-
openapi: "3.0.3",
|
|
1883
|
-
info: {
|
|
1884
|
-
title: "Feishu Bot Info",
|
|
1885
|
-
version: "1.0.0",
|
|
1886
|
-
},
|
|
1887
|
-
servers: [
|
|
1888
|
-
{
|
|
1889
|
-
url: exports.FEISHU_OPENAPI_ENDPOINT,
|
|
1890
|
-
},
|
|
1891
|
-
],
|
|
1892
|
-
// Feishu's docs site does not currently expose this as a stable
|
|
1893
|
-
// machine-readable OpenAPI document to UXC, so keep the tiny operation
|
|
1894
|
-
// schema needed for bot self-identification close to the adapter.
|
|
1895
|
-
paths: {
|
|
1896
|
-
"/bot/v3/info": {
|
|
1897
|
-
get: {
|
|
1898
|
-
operationId: "get:/bot/v3/info",
|
|
1899
|
-
summary: "Get bot information for the current app",
|
|
1900
|
-
responses: {
|
|
1901
|
-
"200": {
|
|
1902
|
-
description: "OK",
|
|
1903
|
-
},
|
|
1904
|
-
},
|
|
1905
|
-
security: [
|
|
1906
|
-
{
|
|
1907
|
-
bearerAuth: [],
|
|
1908
|
-
},
|
|
1909
|
-
],
|
|
1910
|
-
},
|
|
1911
|
-
},
|
|
1912
|
-
},
|
|
1913
|
-
components: {
|
|
1914
|
-
securitySchemes: {
|
|
1915
|
-
bearerAuth: {
|
|
1916
|
-
type: "http",
|
|
1917
|
-
scheme: "bearer",
|
|
1918
|
-
bearerFormat: "tenant_access_token",
|
|
1919
|
-
},
|
|
1920
|
-
},
|
|
1921
|
-
},
|
|
1922
|
-
};
|