@holon-run/agentinbox 0.1.3 → 0.2.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/README.md +1 -0
- package/dist/src/adapters.js +33 -2
- package/dist/src/cli.js +63 -14
- package/dist/src/http.js +85 -7
- package/dist/src/service.js +469 -16
- package/dist/src/source_resolution.js +100 -0
- package/dist/src/source_schema.js +23 -1
- package/dist/src/sources/github.js +73 -1
- package/dist/src/sources/remote.js +24 -0
- package/dist/src/sources/remote_profiles.js +133 -0
- package/dist/src/store.js +129 -6
- package/drizzle/migrations/0002_subscription_cleanup_policy.sql +45 -0
- package/drizzle/migrations/0003_subscription_lifecycle_retirements.sql +14 -0
- package/drizzle/migrations/0004_source_idle_states.sql +10 -0
- package/drizzle/schema.ts +24 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -136,6 +136,7 @@ Create a local source and publish an event:
|
|
|
136
136
|
agentinbox source add local_event local-demo
|
|
137
137
|
agentinbox subscription add <source_id>
|
|
138
138
|
agentinbox subscription add <source_id> --agent-id <agent_id>
|
|
139
|
+
agentinbox subscription add <source_id> --tracked-resource-ref pr:373 --cleanup-policy-json '{"mode":"manual"}'
|
|
139
140
|
agentinbox subscription add <source_id> --filter-file ./filter.json
|
|
140
141
|
cat filter.json | agentinbox subscription add <source_id> --filter-stdin
|
|
141
142
|
agentinbox source event <source_id> --native-id demo-1 --event local.demo
|
package/dist/src/adapters.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AdapterRegistry = void 0;
|
|
4
|
+
const paths_1 = require("./paths");
|
|
4
5
|
const feishu_1 = require("./sources/feishu");
|
|
5
6
|
const github_1 = require("./sources/github");
|
|
6
7
|
const remote_1 = require("./sources/remote");
|
|
8
|
+
const remote_profiles_1 = require("./sources/remote_profiles");
|
|
9
|
+
const source_resolution_1 = require("./source_resolution");
|
|
7
10
|
class NoopSourceAdapter {
|
|
8
11
|
sourceType;
|
|
9
12
|
constructor(sourceType) {
|
|
@@ -37,11 +40,15 @@ class AdapterRegistry {
|
|
|
37
40
|
defaultDelivery = new NoopDeliveryAdapter();
|
|
38
41
|
feishuDelivery = new feishu_1.FeishuDeliveryAdapter();
|
|
39
42
|
githubDelivery = new github_1.GithubDeliveryAdapter();
|
|
43
|
+
homeDir;
|
|
44
|
+
remoteProfileRegistry;
|
|
40
45
|
constructor(store, appendSourceEvent, options) {
|
|
46
|
+
this.homeDir = options?.homeDir ?? (0, paths_1.resolveAgentInboxHome)(process.env);
|
|
47
|
+
this.remoteProfileRegistry = options?.remoteProfileRegistry ?? new remote_profiles_1.RemoteSourceProfileRegistry();
|
|
41
48
|
this.remoteSource = new remote_1.RemoteSourceRuntime(store, appendSourceEvent, {
|
|
42
|
-
homeDir:
|
|
49
|
+
homeDir: this.homeDir,
|
|
43
50
|
client: options?.remoteSourceClient,
|
|
44
|
-
profileRegistry:
|
|
51
|
+
profileRegistry: this.remoteProfileRegistry,
|
|
45
52
|
});
|
|
46
53
|
}
|
|
47
54
|
sourceAdapterFor(type) {
|
|
@@ -109,6 +116,30 @@ class AdapterRegistry {
|
|
|
109
116
|
const adapter = this.sourceAdapterFor(source.sourceType);
|
|
110
117
|
await adapter.removeSource?.(source.sourceId);
|
|
111
118
|
}
|
|
119
|
+
async resolveSourceIdentity(source) {
|
|
120
|
+
return (0, source_resolution_1.resolveSourceIdentity)(source, {
|
|
121
|
+
homeDir: this.homeDir,
|
|
122
|
+
profileRegistry: this.remoteProfileRegistry,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
async resolveSourceSchema(source) {
|
|
126
|
+
return (0, source_resolution_1.resolveSourceSchema)(source, {
|
|
127
|
+
homeDir: this.homeDir,
|
|
128
|
+
profileRegistry: this.remoteProfileRegistry,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
async projectLifecycleSignal(source, rawPayload) {
|
|
132
|
+
if (source.sourceType === "local_event") {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
return this.remoteSource.projectLifecycleSignal(source, rawPayload);
|
|
136
|
+
}
|
|
137
|
+
async expandSubscriptionShortcut(source, input) {
|
|
138
|
+
if (source.sourceType === "local_event") {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
return this.remoteSource.expandSubscriptionShortcut(source, input);
|
|
142
|
+
}
|
|
112
143
|
status() {
|
|
113
144
|
return {
|
|
114
145
|
remote: this.remoteSource.status?.() ?? {},
|
package/dist/src/cli.js
CHANGED
|
@@ -76,11 +76,16 @@ async function main() {
|
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
78
|
if (command === "source" && normalized[1] === "remove") {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
79
|
+
const removeArgs = normalized.slice(2);
|
|
80
|
+
const positionals = positionalArgs(removeArgs, ["--with-subscriptions"]);
|
|
81
|
+
const sourceId = positionals[0];
|
|
82
|
+
if (!sourceId || positionals[1]) {
|
|
83
|
+
throw new Error("usage: agentinbox source remove <sourceId> [--with-subscriptions]");
|
|
82
84
|
}
|
|
83
|
-
|
|
85
|
+
const query = buildQuery({
|
|
86
|
+
with_subscriptions: hasFlag(normalized, "--with-subscriptions") ? "true" : undefined,
|
|
87
|
+
});
|
|
88
|
+
await printRemote(client, `/sources/${encodeURIComponent(sourceId)}${query}`, undefined, "DELETE");
|
|
84
89
|
return;
|
|
85
90
|
}
|
|
86
91
|
if (command === "source" && normalized[1] === "update") {
|
|
@@ -120,11 +125,27 @@ async function main() {
|
|
|
120
125
|
return;
|
|
121
126
|
}
|
|
122
127
|
if (command === "source" && normalized[1] === "schema") {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
128
|
+
if (normalized[2] === "preview") {
|
|
129
|
+
const sourceRef = normalized[3];
|
|
130
|
+
if (!sourceRef) {
|
|
131
|
+
throw new Error("usage: agentinbox source schema preview <sourceKind|sourceType> [--config-json JSON] [--config-ref REF]");
|
|
132
|
+
}
|
|
133
|
+
await printRemote(client, "/sources/schema-preview", {
|
|
134
|
+
sourceRef,
|
|
135
|
+
configRef: takeFlagValue(normalized, "--config-ref") ?? undefined,
|
|
136
|
+
config: (0, util_1.parseJsonArg)(takeFlagValue(normalized, "--config-json")),
|
|
137
|
+
});
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const sourceRef = normalized[2];
|
|
141
|
+
if (!sourceRef) {
|
|
142
|
+
throw new Error("usage: agentinbox source schema <sourceId|sourceType>");
|
|
126
143
|
}
|
|
127
|
-
|
|
144
|
+
if (sourceRef.startsWith("src_")) {
|
|
145
|
+
await printRemote(client, `/sources/${encodeURIComponent(sourceRef)}/schema`, undefined, "GET");
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
await printRemote(client, `/source-types/${encodeURIComponent(sourceRef)}/schema`, undefined, "GET");
|
|
128
149
|
return;
|
|
129
150
|
}
|
|
130
151
|
if (command === "source" && normalized[1] === "poll") {
|
|
@@ -223,19 +244,46 @@ async function main() {
|
|
|
223
244
|
}
|
|
224
245
|
if (command === "subscription" && normalized[1] === "add") {
|
|
225
246
|
const args = normalized.slice(2);
|
|
226
|
-
const positionals = positionalArgs(args, [
|
|
247
|
+
const positionals = positionalArgs(args, [
|
|
248
|
+
"--agent-id",
|
|
249
|
+
"--shortcut",
|
|
250
|
+
"--shortcut-args-json",
|
|
251
|
+
"--filter-json",
|
|
252
|
+
"--filter-file",
|
|
253
|
+
"--tracked-resource-ref",
|
|
254
|
+
"--cleanup-policy-json",
|
|
255
|
+
"--start-policy",
|
|
256
|
+
"--start-offset",
|
|
257
|
+
"--start-time",
|
|
258
|
+
]);
|
|
227
259
|
const sourceId = positionals[0];
|
|
228
260
|
if (!sourceId || positionals[1]) {
|
|
229
|
-
throw new Error("usage: agentinbox subscription add <sourceId> [--agent-id ID] [--filter-json JSON | --filter-file PATH | --filter-stdin] [--start-policy POLICY] [--start-offset N] [--start-time ISO8601]");
|
|
261
|
+
throw new Error("usage: agentinbox subscription add <sourceId> [--agent-id ID] [--shortcut NAME --shortcut-args-json JSON] [--filter-json JSON | --filter-file PATH | --filter-stdin] [--tracked-resource-ref REF] [--cleanup-policy-json JSON] [--start-policy POLICY] [--start-offset N] [--start-time ISO8601]");
|
|
230
262
|
}
|
|
231
263
|
const selection = await selectAgentForCommand(client, {
|
|
232
264
|
explicitAgentId: takeFlagValue(normalized, "--agent-id"),
|
|
233
265
|
autoRegister: true,
|
|
234
266
|
});
|
|
267
|
+
const shortcutName = takeFlagValue(normalized, "--shortcut");
|
|
268
|
+
const shortcutArgsJson = takeFlagValue(normalized, "--shortcut-args-json");
|
|
269
|
+
if (shortcutName && (hasFlag(normalized, "--filter-stdin") || takeFlagValue(normalized, "--filter-json") != null || takeFlagValue(normalized, "--filter-file") != null || takeFlagValue(normalized, "--tracked-resource-ref") != null || takeFlagValue(normalized, "--cleanup-policy-json") != null)) {
|
|
270
|
+
throw new Error("subscription add shortcut does not allow filter, trackedResourceRef, or cleanupPolicy flags");
|
|
271
|
+
}
|
|
272
|
+
const cleanupPolicyJson = takeFlagValue(normalized, "--cleanup-policy-json");
|
|
235
273
|
const response = await requestRemote(client, "/subscriptions", {
|
|
236
274
|
agentId: selection.agentId,
|
|
237
275
|
sourceId,
|
|
238
|
-
|
|
276
|
+
shortcut: shortcutName
|
|
277
|
+
? {
|
|
278
|
+
name: shortcutName,
|
|
279
|
+
args: shortcutArgsJson != null ? (0, util_1.parseJsonArg)(shortcutArgsJson, "--shortcut-args-json") : {},
|
|
280
|
+
}
|
|
281
|
+
: undefined,
|
|
282
|
+
filter: shortcutName ? undefined : readSubscriptionFilter(normalized),
|
|
283
|
+
trackedResourceRef: takeFlagValue(normalized, "--tracked-resource-ref") ?? undefined,
|
|
284
|
+
cleanupPolicy: cleanupPolicyJson != null
|
|
285
|
+
? (0, util_1.parseJsonArg)(cleanupPolicyJson, "--cleanup-policy-json")
|
|
286
|
+
: undefined,
|
|
239
287
|
startPolicy: takeFlagValue(normalized, "--start-policy") ?? undefined,
|
|
240
288
|
startOffset: parseOptionalNumber(takeFlagValue(normalized, "--start-offset")),
|
|
241
289
|
startTime: takeFlagValue(normalized, "--start-time") ?? undefined,
|
|
@@ -741,10 +789,11 @@ Usage:
|
|
|
741
789
|
agentinbox source list
|
|
742
790
|
agentinbox source show <sourceId>
|
|
743
791
|
agentinbox source update <sourceId> [--config-json JSON] [--config-ref REF | --clear-config-ref]
|
|
744
|
-
agentinbox source remove <sourceId>
|
|
792
|
+
agentinbox source remove <sourceId> [--with-subscriptions]
|
|
745
793
|
agentinbox source pause <remoteSourceId>
|
|
746
794
|
agentinbox source resume <remoteSourceId>
|
|
747
|
-
agentinbox source schema <sourceType>
|
|
795
|
+
agentinbox source schema <sourceId|sourceType>
|
|
796
|
+
agentinbox source schema preview <sourceKind|sourceType> [--config-json JSON] [--config-ref REF]
|
|
748
797
|
agentinbox source poll <sourceId>
|
|
749
798
|
agentinbox source event <sourceId> --native-id ID --event EVENT [--occurred-at ISO8601] [--metadata-json JSON] [--payload-json JSON]
|
|
750
799
|
`,
|
|
@@ -763,7 +812,7 @@ Usage:
|
|
|
763
812
|
subscription: `agentinbox subscription
|
|
764
813
|
|
|
765
814
|
Usage:
|
|
766
|
-
agentinbox subscription add <sourceId> [--agent-id ID] [--filter-json JSON | --filter-file PATH | --filter-stdin] [--start-policy POLICY] [--start-offset N] [--start-time ISO8601]
|
|
815
|
+
agentinbox subscription add <sourceId> [--agent-id ID] [--shortcut NAME --shortcut-args-json JSON] [--filter-json JSON | --filter-file PATH | --filter-stdin] [--tracked-resource-ref REF] [--cleanup-policy-json JSON] [--start-policy POLICY] [--start-offset N] [--start-time ISO8601]
|
|
767
816
|
agentinbox subscription list [--source-id ID] [--agent-id ID]
|
|
768
817
|
agentinbox subscription show <subscriptionId>
|
|
769
818
|
agentinbox subscription remove <subscriptionId>
|
package/dist/src/http.js
CHANGED
|
@@ -149,6 +149,26 @@ function buildFastifyServer(service) {
|
|
|
149
149
|
const params = request.params;
|
|
150
150
|
return service.getSourceDetails(decodeURIComponent(params.sourceId));
|
|
151
151
|
});
|
|
152
|
+
app.get("/sources/:sourceId/schema", {
|
|
153
|
+
schema: {
|
|
154
|
+
tags: ["sources"],
|
|
155
|
+
params: {
|
|
156
|
+
type: "object",
|
|
157
|
+
required: ["sourceId"],
|
|
158
|
+
properties: {
|
|
159
|
+
sourceId: { type: "string", minLength: 1 },
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
response: {
|
|
163
|
+
200: jsonObjectSchema,
|
|
164
|
+
400: errorResponseSchema,
|
|
165
|
+
404: errorResponseSchema,
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
}, async (request) => {
|
|
169
|
+
const params = request.params;
|
|
170
|
+
return service.getResolvedSourceSchema(decodeURIComponent(params.sourceId));
|
|
171
|
+
});
|
|
152
172
|
app.delete("/sources/:sourceId", {
|
|
153
173
|
schema: {
|
|
154
174
|
tags: ["sources"],
|
|
@@ -159,6 +179,18 @@ function buildFastifyServer(service) {
|
|
|
159
179
|
sourceId: { type: "string", minLength: 1 },
|
|
160
180
|
},
|
|
161
181
|
},
|
|
182
|
+
querystring: {
|
|
183
|
+
type: "object",
|
|
184
|
+
additionalProperties: false,
|
|
185
|
+
properties: {
|
|
186
|
+
with_subscriptions: {
|
|
187
|
+
anyOf: [
|
|
188
|
+
{ type: "boolean" },
|
|
189
|
+
{ type: "string", enum: ["true", "false", "1", "0"] },
|
|
190
|
+
],
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
},
|
|
162
194
|
response: {
|
|
163
195
|
200: jsonObjectSchema,
|
|
164
196
|
400: errorResponseSchema,
|
|
@@ -166,7 +198,10 @@ function buildFastifyServer(service) {
|
|
|
166
198
|
},
|
|
167
199
|
}, async (request) => {
|
|
168
200
|
const params = request.params;
|
|
169
|
-
|
|
201
|
+
const query = request.query;
|
|
202
|
+
return service.removeSource(decodeURIComponent(params.sourceId), {
|
|
203
|
+
withSubscriptions: query.with_subscriptions === true || query.with_subscriptions === "true" || query.with_subscriptions === "1",
|
|
204
|
+
});
|
|
170
205
|
});
|
|
171
206
|
app.patch("/sources/:sourceId", {
|
|
172
207
|
schema: {
|
|
@@ -250,6 +285,25 @@ function buildFastifyServer(service) {
|
|
|
250
285
|
const params = request.params;
|
|
251
286
|
return service.getSourceSchema(decodeURIComponent(params.sourceType));
|
|
252
287
|
});
|
|
288
|
+
app.post("/sources/schema-preview", {
|
|
289
|
+
schema: {
|
|
290
|
+
tags: ["sources"],
|
|
291
|
+
body: {
|
|
292
|
+
type: "object",
|
|
293
|
+
additionalProperties: false,
|
|
294
|
+
required: ["sourceRef"],
|
|
295
|
+
properties: {
|
|
296
|
+
sourceRef: { type: "string", minLength: 1 },
|
|
297
|
+
configRef: { anyOf: [{ type: "string" }, { type: "null" }] },
|
|
298
|
+
config: jsonObjectSchema,
|
|
299
|
+
},
|
|
300
|
+
},
|
|
301
|
+
response: {
|
|
302
|
+
200: jsonObjectSchema,
|
|
303
|
+
400: errorResponseSchema,
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
}, async (request) => service.previewSourceSchema(request.body));
|
|
253
307
|
app.post("/sources/:sourceId/poll", {
|
|
254
308
|
schema: {
|
|
255
309
|
tags: ["sources"],
|
|
@@ -549,9 +603,18 @@ function buildFastifyServer(service) {
|
|
|
549
603
|
properties: {
|
|
550
604
|
agentId: { type: "string", minLength: 1 },
|
|
551
605
|
sourceId: { type: "string", minLength: 1 },
|
|
606
|
+
shortcut: {
|
|
607
|
+
type: "object",
|
|
608
|
+
additionalProperties: false,
|
|
609
|
+
required: ["name"],
|
|
610
|
+
properties: {
|
|
611
|
+
name: { type: "string", minLength: 1 },
|
|
612
|
+
args: jsonObjectSchema,
|
|
613
|
+
},
|
|
614
|
+
},
|
|
552
615
|
filter: jsonObjectSchema,
|
|
553
|
-
|
|
554
|
-
|
|
616
|
+
trackedResourceRef: { type: "string" },
|
|
617
|
+
cleanupPolicy: jsonObjectSchema,
|
|
555
618
|
startPolicy: { type: "string" },
|
|
556
619
|
startOffset: { type: "integer" },
|
|
557
620
|
startTime: { type: "string" },
|
|
@@ -567,9 +630,17 @@ function buildFastifyServer(service) {
|
|
|
567
630
|
return service.registerSubscription({
|
|
568
631
|
agentId: String(body.agentId),
|
|
569
632
|
sourceId: String(body.sourceId),
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
633
|
+
shortcut: body.shortcut && typeof body.shortcut === "object"
|
|
634
|
+
? {
|
|
635
|
+
name: String(body.shortcut.name),
|
|
636
|
+
args: body.shortcut.args ?? undefined,
|
|
637
|
+
}
|
|
638
|
+
: undefined,
|
|
639
|
+
filter: body.filter && typeof body.filter === "object"
|
|
640
|
+
? body.filter
|
|
641
|
+
: undefined,
|
|
642
|
+
trackedResourceRef: optionalString(body.trackedResourceRef) ?? null,
|
|
643
|
+
cleanupPolicy: body.cleanupPolicy,
|
|
573
644
|
startPolicy: optionalString(body.startPolicy),
|
|
574
645
|
startOffset: typeof body.startOffset === "number" ? body.startOffset : undefined,
|
|
575
646
|
startTime: optionalString(body.startTime) ?? undefined,
|
|
@@ -999,9 +1070,16 @@ function isBadRequestError(message) {
|
|
|
999
1070
|
message.startsWith("subscriptions requires") ||
|
|
1000
1071
|
message.startsWith("agent register conflict") ||
|
|
1001
1072
|
message.startsWith("unsupported activation target kind") ||
|
|
1002
|
-
message.startsWith("unsupported
|
|
1073
|
+
message.startsWith("unsupported cleanup policy mode") ||
|
|
1003
1074
|
message.startsWith("unsupported start policy") ||
|
|
1004
1075
|
message.startsWith("unsupported terminal") ||
|
|
1076
|
+
message.startsWith("cleanupPolicy ") ||
|
|
1077
|
+
message.startsWith("trackedResourceRef ") ||
|
|
1078
|
+
message.startsWith("preview failed: ") ||
|
|
1079
|
+
message.startsWith("unknown source kind or type for preview") ||
|
|
1080
|
+
message.startsWith("preview source kind ") ||
|
|
1081
|
+
message.startsWith("subscription add shortcut") ||
|
|
1082
|
+
message.startsWith("unknown subscription shortcut ") ||
|
|
1005
1083
|
message.startsWith("expected boolean") ||
|
|
1006
1084
|
message.startsWith("expected integer") ||
|
|
1007
1085
|
message.startsWith("expected positive integer") ||
|