@okrlinkhub/agent-factory 0.2.12 → 0.2.14

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.
@@ -260,6 +260,23 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
260
260
  },
261
261
  Name
262
262
  >;
263
+ clearDeprecatedAgentProfileFields: FunctionReference<
264
+ "mutation",
265
+ "internal",
266
+ { dryRun?: boolean },
267
+ {
268
+ clearedClientMd: number;
269
+ clearedProviderUserId: number;
270
+ clearedSkills: number;
271
+ clearedSoulMd: number;
272
+ dryRun: boolean;
273
+ scanned: number;
274
+ unchanged: number;
275
+ updated: number;
276
+ updatedAgentKeys: Array<string>;
277
+ },
278
+ Name
279
+ >;
263
280
  complete: FunctionReference<
264
281
  "mutation",
265
282
  "internal",
@@ -299,8 +316,8 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
299
316
  enabled: boolean;
300
317
  providerUserId?: string;
301
318
  secretsRef: Array<string>;
302
- skills: Array<string>;
303
- soulMd: string;
319
+ skills?: Array<string>;
320
+ soulMd?: string;
304
321
  version: string;
305
322
  },
306
323
  string,
@@ -704,6 +721,13 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
704
721
  }>,
705
722
  Name
706
723
  >;
724
+ messageRuntimeConfig: FunctionReference<
725
+ "query",
726
+ "internal",
727
+ {},
728
+ null | { systemPrompt?: string },
729
+ Name
730
+ >;
707
731
  providerRuntimeConfig: FunctionReference<
708
732
  "query",
709
733
  "internal",
@@ -823,6 +847,13 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
823
847
  },
824
848
  Name
825
849
  >;
850
+ setMessageRuntimeConfig: FunctionReference<
851
+ "mutation",
852
+ "internal",
853
+ { messageConfig: { systemPrompt?: string }; nowMs?: number },
854
+ null,
855
+ Name
856
+ >;
826
857
  setProviderRuntimeConfig: FunctionReference<
827
858
  "mutation",
828
859
  "internal",
@@ -1242,6 +1273,23 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
1242
1273
  },
1243
1274
  Name
1244
1275
  >;
1276
+ clearDeprecatedAgentProfileFields: FunctionReference<
1277
+ "mutation",
1278
+ "internal",
1279
+ { dryRun?: boolean },
1280
+ {
1281
+ clearedClientMd: number;
1282
+ clearedProviderUserId: number;
1283
+ clearedSkills: number;
1284
+ clearedSoulMd: number;
1285
+ dryRun: boolean;
1286
+ scanned: number;
1287
+ unchanged: number;
1288
+ updated: number;
1289
+ updatedAgentKeys: Array<string>;
1290
+ },
1291
+ Name
1292
+ >;
1245
1293
  completeJob: FunctionReference<
1246
1294
  "mutation",
1247
1295
  "internal",
@@ -1264,6 +1312,44 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
1264
1312
  boolean,
1265
1313
  Name
1266
1314
  >;
1315
+ deleteGlobalSkill: FunctionReference<
1316
+ "mutation",
1317
+ "internal",
1318
+ { slug: string },
1319
+ {
1320
+ deleted: boolean;
1321
+ deletedReleases: number;
1322
+ deletedVersions: number;
1323
+ slug: string;
1324
+ },
1325
+ Name
1326
+ >;
1327
+ deployGlobalSkill: FunctionReference<
1328
+ "mutation",
1329
+ "internal",
1330
+ {
1331
+ actor?: string;
1332
+ description?: string;
1333
+ displayName?: string;
1334
+ entryPoint?: string;
1335
+ moduleFormat?: "esm" | "cjs";
1336
+ nowMs?: number;
1337
+ releaseChannel?: "stable" | "canary";
1338
+ slug: string;
1339
+ sourceJs: string;
1340
+ version: string;
1341
+ },
1342
+ {
1343
+ releaseChannel: "stable" | "canary";
1344
+ releaseId: string;
1345
+ sha256: string;
1346
+ skillId: string;
1347
+ slug: string;
1348
+ version: string;
1349
+ versionId: string;
1350
+ },
1351
+ Name
1352
+ >;
1267
1353
  enqueueMessage: FunctionReference<
1268
1354
  "mutation",
1269
1355
  "internal",
@@ -1441,6 +1527,30 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
1441
1527
  { shouldStop: boolean },
1442
1528
  Name
1443
1529
  >;
1530
+ getWorkerGlobalSkillsManifest: FunctionReference<
1531
+ "query",
1532
+ "internal",
1533
+ {
1534
+ releaseChannel?: "stable" | "canary";
1535
+ workerId?: string;
1536
+ workspaceId?: string;
1537
+ },
1538
+ {
1539
+ generatedAt: number;
1540
+ manifestVersion: string;
1541
+ releaseChannel: "stable" | "canary";
1542
+ skills: Array<{
1543
+ entryPoint: string;
1544
+ moduleFormat: "esm" | "cjs";
1545
+ sha256: string;
1546
+ slug: string;
1547
+ sourceJs: string;
1548
+ version: string;
1549
+ }>;
1550
+ workspaceId: string;
1551
+ },
1552
+ Name
1553
+ >;
1444
1554
  getWorkerStats: FunctionReference<
1445
1555
  "query",
1446
1556
  "internal",
@@ -1489,6 +1599,34 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
1489
1599
  { secretId: string; secretRef: string; version: number },
1490
1600
  Name
1491
1601
  >;
1602
+ listGlobalSkills: FunctionReference<
1603
+ "query",
1604
+ "internal",
1605
+ {
1606
+ limit?: number;
1607
+ releaseChannel?: "stable" | "canary";
1608
+ status?: "active" | "disabled";
1609
+ },
1610
+ Array<{
1611
+ activeRelease: null | {
1612
+ activatedAt: number;
1613
+ entryPoint: string;
1614
+ moduleFormat: "esm" | "cjs";
1615
+ releaseChannel: "stable" | "canary";
1616
+ releaseId: string;
1617
+ sha256: string;
1618
+ version: string;
1619
+ versionId: string;
1620
+ };
1621
+ description?: string;
1622
+ displayName: string;
1623
+ skillId: string;
1624
+ slug: string;
1625
+ status: "active" | "disabled";
1626
+ updatedAt: number;
1627
+ }>,
1628
+ Name
1629
+ >;
1492
1630
  listJobsByStatus: FunctionReference<
1493
1631
  "query",
1494
1632
  "internal",
@@ -1510,6 +1648,13 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
1510
1648
  }>,
1511
1649
  Name
1512
1650
  >;
1651
+ messageRuntimeConfig: FunctionReference<
1652
+ "query",
1653
+ "internal",
1654
+ {},
1655
+ null | { systemPrompt?: string },
1656
+ Name
1657
+ >;
1513
1658
  prepareDataSnapshotUpload: FunctionReference<
1514
1659
  "mutation",
1515
1660
  "internal",
@@ -1547,6 +1692,25 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
1547
1692
  { requeued: number; unlocked: number },
1548
1693
  Name
1549
1694
  >;
1695
+ setGlobalSkillStatus: FunctionReference<
1696
+ "mutation",
1697
+ "internal",
1698
+ {
1699
+ actor?: string;
1700
+ nowMs?: number;
1701
+ slug: string;
1702
+ status: "active" | "disabled";
1703
+ },
1704
+ { slug: string; status: "active" | "disabled"; updated: boolean },
1705
+ Name
1706
+ >;
1707
+ setMessageRuntimeConfig: FunctionReference<
1708
+ "mutation",
1709
+ "internal",
1710
+ { messageConfig: { systemPrompt?: string }; nowMs?: number },
1711
+ null,
1712
+ Name
1713
+ >;
1550
1714
  setProviderRuntimeConfig: FunctionReference<
1551
1715
  "mutation",
1552
1716
  "internal",
@@ -1583,8 +1747,8 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
1583
1747
  enabled: boolean;
1584
1748
  providerUserId?: string;
1585
1749
  secretsRef: Array<string>;
1586
- skills: Array<string>;
1587
- soulMd: string;
1750
+ skills?: Array<string>;
1751
+ soulMd?: string;
1588
1752
  version: string;
1589
1753
  },
1590
1754
  string,
@@ -77,6 +77,11 @@ export const DEFAULT_WORKER_RUNTIME_ENV: Record<string, string> = {
77
77
  OPENCLAW_GATEWAY_READY_TIMEOUT_MS: "60000",
78
78
  OPENCLAW_GATEWAY_READY_POLL_MS: "500",
79
79
  OPENCLAW_GATEWAY_READY_REQUIRED: "true",
80
+ SKILLS_BOOTSTRAP_MODE: "db_manifest",
81
+ SKILLS_BOOTSTRAP_REQUIRED: "false",
82
+ SKILLS_BOOTSTRAP_TIMEOUT_MS: "15000",
83
+ SKILLS_RELEASE_CHANNEL: "stable",
84
+ OPENCLAW_SKILLS_DIR: "/data/workspace/skills",
80
85
  };
81
86
 
82
87
  export const queuePolicyValidator = v.object({
@@ -52,6 +52,181 @@ describe("component lib", () => {
52
52
  expect(claimed?.conversationId).toBe("telegram:chat:1");
53
53
  });
54
54
 
55
+ test("minimal agent profile should work when payload provides providerUserId", async () => {
56
+ const t = initConvexTest();
57
+ await t.mutation(api.queue.upsertAgentProfile, {
58
+ agentKey: "minimal-agent",
59
+ version: "1.0.0",
60
+ secretsRef: [],
61
+ enabled: true,
62
+ });
63
+
64
+ const messageId = await t.mutation(api.lib.enqueue, {
65
+ conversationId: "telegram:chat:minimal",
66
+ agentKey: "minimal-agent",
67
+ payload: {
68
+ provider: "telegram",
69
+ providerUserId: "u-minimal-1",
70
+ messageText: "hello",
71
+ },
72
+ });
73
+
74
+ const claim = await t.mutation(api.lib.claim, {
75
+ workerId: "worker-minimal-1",
76
+ });
77
+ expect(claim?.messageId).toBe(messageId);
78
+ expect(claim?.payload.providerUserId).toBe("u-minimal-1");
79
+
80
+ const bundle = await t.query(api.lib.getHydrationBundle, {
81
+ messageId,
82
+ workspaceId: "default",
83
+ });
84
+ expect(bundle).not.toBeNull();
85
+ expect(bundle?.payload.providerUserId).toBe("u-minimal-1");
86
+ expect(bundle?.bridgeRuntimeConfig).toBeNull();
87
+ });
88
+
89
+ test("enqueue should append global system prompt to queued message", async () => {
90
+ const t = initConvexTest();
91
+ await t.mutation(api.queue.upsertAgentProfile, {
92
+ agentKey: "system-prompt-agent",
93
+ version: "1.0.0",
94
+ secretsRef: [],
95
+ enabled: true,
96
+ });
97
+ await t.mutation(api.lib.setMessageRuntimeConfig, {
98
+ messageConfig: {
99
+ systemPrompt: " Rispondi sempre con un breve riassunto finale. ",
100
+ },
101
+ });
102
+
103
+ const storedMessageConfig = await t.query(api.lib.messageRuntimeConfig, {});
104
+ expect(storedMessageConfig).toEqual({
105
+ systemPrompt: "Rispondi sempre con un breve riassunto finale.",
106
+ });
107
+
108
+ const messageId = await t.mutation(api.lib.enqueue, {
109
+ conversationId: "telegram:chat:system-prompt",
110
+ agentKey: "system-prompt-agent",
111
+ payload: {
112
+ provider: "telegram",
113
+ providerUserId: "u-system-prompt-1",
114
+ messageText: "Come va?",
115
+ },
116
+ });
117
+
118
+ const claim = await t.mutation(api.lib.claim, {
119
+ workerId: "worker-system-prompt-1",
120
+ });
121
+ expect(claim?.messageId).toBe(messageId);
122
+ expect(claim?.payload.messageText).toBe(
123
+ "Come va?\n\nRispondi sempre con un breve riassunto finale.",
124
+ );
125
+ });
126
+
127
+ test("blank global system prompt should not modify queued messages", async () => {
128
+ const t = initConvexTest();
129
+ await t.mutation(api.queue.upsertAgentProfile, {
130
+ agentKey: "blank-system-prompt-agent",
131
+ version: "1.0.0",
132
+ secretsRef: [],
133
+ enabled: true,
134
+ });
135
+ await t.mutation(api.lib.setMessageRuntimeConfig, {
136
+ messageConfig: {
137
+ systemPrompt: " ",
138
+ },
139
+ });
140
+
141
+ const storedMessageConfig = await t.query(api.lib.messageRuntimeConfig, {});
142
+ expect(storedMessageConfig).toBeNull();
143
+
144
+ const messageId = await t.mutation(api.lib.enqueue, {
145
+ conversationId: "telegram:chat:blank-system-prompt",
146
+ agentKey: "blank-system-prompt-agent",
147
+ payload: {
148
+ provider: "telegram",
149
+ providerUserId: "u-blank-system-prompt-1",
150
+ messageText: "hello",
151
+ },
152
+ });
153
+
154
+ const claim = await t.mutation(api.lib.claim, {
155
+ workerId: "worker-blank-system-prompt-1",
156
+ });
157
+ expect(claim?.messageId).toBe(messageId);
158
+ expect(claim?.payload.messageText).toBe("hello");
159
+ });
160
+
161
+ test("enqueue should fail when providerUserId is blank in both profile and payload", async () => {
162
+ const t = initConvexTest();
163
+ await t.mutation(api.queue.upsertAgentProfile, {
164
+ agentKey: "missing-provider-user-agent",
165
+ version: "1.0.0",
166
+ providerUserId: " ",
167
+ secretsRef: [],
168
+ enabled: true,
169
+ });
170
+
171
+ await expect(
172
+ t.mutation(api.queue.enqueueMessage, {
173
+ conversationId: "telegram:chat:missing-provider-user",
174
+ agentKey: "missing-provider-user-agent",
175
+ payload: {
176
+ provider: "telegram",
177
+ providerUserId: " ",
178
+ messageText: "hello",
179
+ },
180
+ }),
181
+ ).rejects.toThrow("providerUserId is required but missing");
182
+ });
183
+
184
+ test("clearDeprecatedAgentProfileFields should remove deprecated profile fields", async () => {
185
+ const t = initConvexTest();
186
+ await t.mutation(api.queue.upsertAgentProfile, {
187
+ agentKey: "cleanup-agent",
188
+ version: "1.0.0",
189
+ providerUserId: "legacy-user-1",
190
+ soulMd: "# Legacy Soul",
191
+ clientMd: "# Legacy Client",
192
+ skills: ["agent-bridge"],
193
+ secretsRef: [],
194
+ enabled: true,
195
+ });
196
+ await t.mutation(api.queue.upsertAgentProfile, {
197
+ agentKey: "already-clean-agent",
198
+ version: "1.0.0",
199
+ secretsRef: [],
200
+ enabled: true,
201
+ });
202
+
203
+ const dryRun = await t.mutation((api.lib as any).clearDeprecatedAgentProfileFields, {
204
+ dryRun: true,
205
+ });
206
+ expect(dryRun.dryRun).toBe(true);
207
+ expect(dryRun.scanned).toBe(2);
208
+ expect(dryRun.updated).toBe(1);
209
+ expect(dryRun.unchanged).toBe(1);
210
+ expect(dryRun.clearedProviderUserId).toBe(1);
211
+ expect(dryRun.clearedSoulMd).toBe(1);
212
+ expect(dryRun.clearedClientMd).toBe(1);
213
+ expect(dryRun.clearedSkills).toBe(1);
214
+ expect(dryRun.updatedAgentKeys).toEqual(["cleanup-agent"]);
215
+
216
+ const cleanup = await t.mutation((api.lib as any).clearDeprecatedAgentProfileFields, {});
217
+ expect(cleanup.dryRun).toBe(false);
218
+ expect(cleanup.updated).toBe(1);
219
+ expect(cleanup.updatedAgentKeys).toEqual(["cleanup-agent"]);
220
+
221
+ const secondPass = await t.mutation((api.lib as any).clearDeprecatedAgentProfileFields, {});
222
+ expect(secondPass.updated).toBe(0);
223
+ expect(secondPass.unchanged).toBe(2);
224
+ expect(secondPass.clearedProviderUserId).toBe(0);
225
+ expect(secondPass.clearedSoulMd).toBe(0);
226
+ expect(secondPass.clearedClientMd).toBe(0);
227
+ expect(secondPass.clearedSkills).toBe(0);
228
+ });
229
+
55
230
  test("identity binding should resolve, rebind and revoke", async () => {
56
231
  const t = initConvexTest();
57
232
  await t.mutation(api.queue.upsertAgentProfile, {
@@ -1,9 +1,12 @@
1
1
  export {
2
2
  upsertAgentProfile as configureAgent,
3
+ clearDeprecatedAgentProfileFields,
3
4
  importPlaintextSecret as importSecret,
4
5
  getSecretsStatus as secretStatus,
5
6
  providerRuntimeConfig,
6
7
  setProviderRuntimeConfig,
8
+ messageRuntimeConfig,
9
+ setMessageRuntimeConfig,
7
10
  enqueueMessage as enqueue,
8
11
  releaseStuckJobs,
9
12
  appendConversationMessages,