@bopen-io/clawnet-plugin 0.0.2 → 0.0.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/dist/constants.js +4 -7
- package/dist/constants.js.map +2 -2
- package/dist/ui/index.js +12 -6
- package/dist/ui/index.js.map +2 -2
- package/dist/worker.js +79 -44
- package/dist/worker.js.map +2 -2
- package/package.json +1 -1
package/dist/worker.js
CHANGED
|
@@ -6239,8 +6239,7 @@ function createClawNetClient(config) {
|
|
|
6239
6239
|
|
|
6240
6240
|
// src/constants.ts
|
|
6241
6241
|
var JOB_KEYS = {
|
|
6242
|
-
sync: "clawnet-sync"
|
|
6243
|
-
clawnetSync: "clawnet-sync"
|
|
6242
|
+
sync: "clawnet-sync"
|
|
6244
6243
|
};
|
|
6245
6244
|
var TOOL_NAMES = {
|
|
6246
6245
|
agentLookup: "agent-lookup",
|
|
@@ -6248,14 +6247,12 @@ var TOOL_NAMES = {
|
|
|
6248
6247
|
fleetOverview: "fleet-overview"
|
|
6249
6248
|
};
|
|
6250
6249
|
var STREAM_CHANNELS = {
|
|
6251
|
-
fleetStatus: "fleet-status",
|
|
6252
|
-
syncProgress: "sync-progress"
|
|
6250
|
+
fleetStatus: "clawnet:fleet-status",
|
|
6251
|
+
syncProgress: "clawnet:sync-progress"
|
|
6253
6252
|
};
|
|
6254
6253
|
var ENTITY_TYPES = {
|
|
6255
6254
|
agent: "clawnet-agent",
|
|
6256
|
-
skill: "clawnet-skill"
|
|
6257
|
-
clawnetAgent: "clawnet-agent",
|
|
6258
|
-
clawnetSkill: "clawnet-skill"
|
|
6255
|
+
skill: "clawnet-skill"
|
|
6259
6256
|
};
|
|
6260
6257
|
var DATA_KEYS = {
|
|
6261
6258
|
clawnetAgents: "clawnet-agents",
|
|
@@ -6272,6 +6269,11 @@ var STATE_KEYS = {
|
|
|
6272
6269
|
syncCursor: "clawnet-sync-cursor",
|
|
6273
6270
|
clawnetLink: "clawnet-link"
|
|
6274
6271
|
};
|
|
6272
|
+
var DEFAULT_CONFIG = {
|
|
6273
|
+
clawnetApiUrl: "https://clawnet.sh",
|
|
6274
|
+
clawnetApiKey: "",
|
|
6275
|
+
syncIntervalMinutes: 15
|
|
6276
|
+
};
|
|
6275
6277
|
|
|
6276
6278
|
// src/worker.ts
|
|
6277
6279
|
var currentContext = null;
|
|
@@ -6317,7 +6319,7 @@ async function performSync(ctx, streamProgress) {
|
|
|
6317
6319
|
const config = await getConfig(ctx);
|
|
6318
6320
|
const apiKey = await resolveApiKey(ctx, config);
|
|
6319
6321
|
const client = createClawNetClient({
|
|
6320
|
-
baseUrl: config.clawnetApiUrl ||
|
|
6322
|
+
baseUrl: config.clawnetApiUrl || DEFAULT_CONFIG.clawnetApiUrl,
|
|
6321
6323
|
apiKey,
|
|
6322
6324
|
fetchFn: ctx.http.fetch.bind(ctx.http)
|
|
6323
6325
|
});
|
|
@@ -6333,19 +6335,23 @@ async function performSync(ctx, streamProgress) {
|
|
|
6333
6335
|
message: "Fetching agents from ClawNet registry..."
|
|
6334
6336
|
});
|
|
6335
6337
|
}
|
|
6336
|
-
const agentResponse = await client.listAgents();
|
|
6337
6338
|
let agentCount = 0;
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6339
|
+
let agentCursor;
|
|
6340
|
+
do {
|
|
6341
|
+
const agentResponse = await client.listAgents({ cursor: agentCursor });
|
|
6342
|
+
for (const agent of agentResponse.agents) {
|
|
6343
|
+
await ctx.entities.upsert({
|
|
6344
|
+
entityType: ENTITY_TYPES.agent,
|
|
6345
|
+
scopeKind: "instance",
|
|
6346
|
+
externalId: agent.slug || agent._id,
|
|
6347
|
+
title: agent.displayName || agent.name,
|
|
6348
|
+
status: agent.deleted ? "deleted" : "active",
|
|
6349
|
+
data: agent
|
|
6350
|
+
});
|
|
6351
|
+
agentCount++;
|
|
6352
|
+
}
|
|
6353
|
+
agentCursor = agentResponse.hasMore ? agentResponse.cursor : void 0;
|
|
6354
|
+
} while (agentCursor);
|
|
6349
6355
|
if (streamProgress) {
|
|
6350
6356
|
ctx.streams.emit(STREAM_CHANNELS.syncProgress, {
|
|
6351
6357
|
phase: "agents",
|
|
@@ -6361,19 +6367,23 @@ async function performSync(ctx, streamProgress) {
|
|
|
6361
6367
|
message: "Fetching skills from ClawNet registry..."
|
|
6362
6368
|
});
|
|
6363
6369
|
}
|
|
6364
|
-
const skillResponse = await client.listSkills();
|
|
6365
6370
|
let skillCount = 0;
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6371
|
+
let skillCursor;
|
|
6372
|
+
do {
|
|
6373
|
+
const skillResponse = await client.listSkills({ cursor: skillCursor });
|
|
6374
|
+
for (const skill of skillResponse.skills) {
|
|
6375
|
+
await ctx.entities.upsert({
|
|
6376
|
+
entityType: ENTITY_TYPES.skill,
|
|
6377
|
+
scopeKind: "instance",
|
|
6378
|
+
externalId: skill.slug || skill._id,
|
|
6379
|
+
title: skill.name,
|
|
6380
|
+
status: "available",
|
|
6381
|
+
data: skill
|
|
6382
|
+
});
|
|
6383
|
+
skillCount++;
|
|
6384
|
+
}
|
|
6385
|
+
skillCursor = skillResponse.hasMore ? skillResponse.cursor : void 0;
|
|
6386
|
+
} while (skillCursor);
|
|
6377
6387
|
if (streamProgress) {
|
|
6378
6388
|
ctx.streams.emit(STREAM_CHANNELS.syncProgress, {
|
|
6379
6389
|
phase: "skills",
|
|
@@ -6407,7 +6417,7 @@ async function performSync(ctx, streamProgress) {
|
|
|
6407
6417
|
return cursor;
|
|
6408
6418
|
}
|
|
6409
6419
|
function registerJobHandlers(ctx) {
|
|
6410
|
-
ctx.jobs.register(JOB_KEYS.
|
|
6420
|
+
ctx.jobs.register(JOB_KEYS.sync, async (job) => {
|
|
6411
6421
|
ctx.logger.info("Starting scheduled ClawNet sync", {
|
|
6412
6422
|
runId: job.runId,
|
|
6413
6423
|
trigger: job.trigger
|
|
@@ -6452,7 +6462,7 @@ function registerEventHandlers(ctx) {
|
|
|
6452
6462
|
const agent = await ctx.agents.get(event.entityId, event.companyId);
|
|
6453
6463
|
if (!agent) return;
|
|
6454
6464
|
const clawnetAgents = await ctx.entities.list({
|
|
6455
|
-
entityType: ENTITY_TYPES.
|
|
6465
|
+
entityType: ENTITY_TYPES.agent,
|
|
6456
6466
|
limit: 200
|
|
6457
6467
|
});
|
|
6458
6468
|
const matchingTemplate = clawnetAgents.find((entity) => {
|
|
@@ -6484,7 +6494,7 @@ function registerDataHandlers(ctx) {
|
|
|
6484
6494
|
ctx.data.register(DATA_KEYS.clawnetAgents, async (params) => {
|
|
6485
6495
|
const { search, limit } = getListParams(params);
|
|
6486
6496
|
const entities = await ctx.entities.list({
|
|
6487
|
-
entityType: ENTITY_TYPES.
|
|
6497
|
+
entityType: ENTITY_TYPES.agent,
|
|
6488
6498
|
limit,
|
|
6489
6499
|
offset: 0
|
|
6490
6500
|
});
|
|
@@ -6503,7 +6513,7 @@ function registerDataHandlers(ctx) {
|
|
|
6503
6513
|
ctx.data.register(DATA_KEYS.clawnetSkills, async (params) => {
|
|
6504
6514
|
const { search, limit } = getListParams(params);
|
|
6505
6515
|
const entities = await ctx.entities.list({
|
|
6506
|
-
entityType: ENTITY_TYPES.
|
|
6516
|
+
entityType: ENTITY_TYPES.skill,
|
|
6507
6517
|
limit,
|
|
6508
6518
|
offset: 0
|
|
6509
6519
|
});
|
|
@@ -6536,7 +6546,7 @@ function registerDataHandlers(ctx) {
|
|
|
6536
6546
|
const [paperclipAgents, clawnetEntities] = await Promise.all([
|
|
6537
6547
|
ctx.agents.list({ companyId, limit: 200, offset: 0 }),
|
|
6538
6548
|
ctx.entities.list({
|
|
6539
|
-
entityType: ENTITY_TYPES.
|
|
6549
|
+
entityType: ENTITY_TYPES.agent,
|
|
6540
6550
|
limit: 200,
|
|
6541
6551
|
offset: 0
|
|
6542
6552
|
})
|
|
@@ -6604,7 +6614,7 @@ function registerActionHandlers(ctx) {
|
|
|
6604
6614
|
throw new Error(`Agent ${agentId} not found`);
|
|
6605
6615
|
}
|
|
6606
6616
|
const clawnetEntities = await ctx.entities.list({
|
|
6607
|
-
entityType: ENTITY_TYPES.
|
|
6617
|
+
entityType: ENTITY_TYPES.agent,
|
|
6608
6618
|
externalId: clawnetExternalId,
|
|
6609
6619
|
limit: 1
|
|
6610
6620
|
});
|
|
@@ -6637,6 +6647,27 @@ function registerActionHandlers(ctx) {
|
|
|
6637
6647
|
templateTitle: clawnetEntities[0].title
|
|
6638
6648
|
};
|
|
6639
6649
|
});
|
|
6650
|
+
ctx.actions.register(ACTION_KEYS.validateConfig, async (_params) => {
|
|
6651
|
+
const config = await getConfig(ctx);
|
|
6652
|
+
const errors = [];
|
|
6653
|
+
if (config.clawnetApiUrl) {
|
|
6654
|
+
try {
|
|
6655
|
+
new URL(config.clawnetApiUrl);
|
|
6656
|
+
} catch {
|
|
6657
|
+
errors.push("Invalid API URL");
|
|
6658
|
+
}
|
|
6659
|
+
}
|
|
6660
|
+
if (config.clawnetApiKey) {
|
|
6661
|
+
try {
|
|
6662
|
+
await ctx.secrets.resolve(config.clawnetApiKey);
|
|
6663
|
+
} catch (e) {
|
|
6664
|
+
errors.push("API key resolution failed: " + summarizeError(e));
|
|
6665
|
+
}
|
|
6666
|
+
} else {
|
|
6667
|
+
errors.push("No API key configured");
|
|
6668
|
+
}
|
|
6669
|
+
return { ok: errors.length === 0, errors };
|
|
6670
|
+
});
|
|
6640
6671
|
}
|
|
6641
6672
|
function registerToolHandlers(ctx) {
|
|
6642
6673
|
ctx.tools.register(
|
|
@@ -6661,7 +6692,7 @@ function registerToolHandlers(ctx) {
|
|
|
6661
6692
|
return { error: "slug is required" };
|
|
6662
6693
|
}
|
|
6663
6694
|
const entities = await ctx.entities.list({
|
|
6664
|
-
entityType: ENTITY_TYPES.
|
|
6695
|
+
entityType: ENTITY_TYPES.agent,
|
|
6665
6696
|
externalId: slug,
|
|
6666
6697
|
limit: 1
|
|
6667
6698
|
});
|
|
@@ -6673,7 +6704,7 @@ function registerToolHandlers(ctx) {
|
|
|
6673
6704
|
};
|
|
6674
6705
|
}
|
|
6675
6706
|
const allAgents = await ctx.entities.list({
|
|
6676
|
-
entityType: ENTITY_TYPES.
|
|
6707
|
+
entityType: ENTITY_TYPES.agent,
|
|
6677
6708
|
limit: 200
|
|
6678
6709
|
});
|
|
6679
6710
|
const term = slug.toLowerCase();
|
|
@@ -6722,7 +6753,7 @@ function registerToolHandlers(ctx) {
|
|
|
6722
6753
|
}
|
|
6723
6754
|
const resultLimit = Math.min(maxResults ?? 10, 50);
|
|
6724
6755
|
const allSkills = await ctx.entities.list({
|
|
6725
|
-
entityType: ENTITY_TYPES.
|
|
6756
|
+
entityType: ENTITY_TYPES.skill,
|
|
6726
6757
|
limit: 200
|
|
6727
6758
|
});
|
|
6728
6759
|
const term = query.toLowerCase();
|
|
@@ -6762,8 +6793,8 @@ function registerToolHandlers(ctx) {
|
|
|
6762
6793
|
},
|
|
6763
6794
|
async (_params, runCtx) => {
|
|
6764
6795
|
const [agents, skills, cursor, paperclipAgents] = await Promise.all([
|
|
6765
|
-
ctx.entities.list({ entityType: ENTITY_TYPES.
|
|
6766
|
-
ctx.entities.list({ entityType: ENTITY_TYPES.
|
|
6796
|
+
ctx.entities.list({ entityType: ENTITY_TYPES.agent, limit: 200 }),
|
|
6797
|
+
ctx.entities.list({ entityType: ENTITY_TYPES.skill, limit: 200 }),
|
|
6767
6798
|
getSyncCursor(ctx),
|
|
6768
6799
|
ctx.agents.list({ companyId: runCtx.companyId, limit: 200, offset: 0 })
|
|
6769
6800
|
]);
|
|
@@ -6860,6 +6891,10 @@ var plugin = definePlugin({
|
|
|
6860
6891
|
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
6861
6892
|
errors.push("clawnetApiUrl must use http or https protocol");
|
|
6862
6893
|
}
|
|
6894
|
+
const hostname = url.hostname;
|
|
6895
|
+
if (hostname === "localhost" || hostname.startsWith("127.") || hostname.startsWith("10.") || hostname.startsWith("192.168.") || hostname.startsWith("169.254.") || /^172\.(1[6-9]|2\d|3[01])\./.test(hostname) || hostname.endsWith(".internal") || hostname.endsWith(".local")) {
|
|
6896
|
+
errors.push("clawnetApiUrl must not point to a private or internal address");
|
|
6897
|
+
}
|
|
6863
6898
|
} catch {
|
|
6864
6899
|
errors.push("clawnetApiUrl is not a valid URL");
|
|
6865
6900
|
}
|
|
@@ -6883,7 +6918,7 @@ var plugin = definePlugin({
|
|
|
6883
6918
|
}
|
|
6884
6919
|
}
|
|
6885
6920
|
if (!typed.clawnetApiUrl) {
|
|
6886
|
-
warnings.push(
|
|
6921
|
+
warnings.push(`clawnetApiUrl not set; will default to ${DEFAULT_CONFIG.clawnetApiUrl}`);
|
|
6887
6922
|
}
|
|
6888
6923
|
return {
|
|
6889
6924
|
ok: errors.length === 0,
|