@okrlinkhub/agent-factory 0.2.13 → 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.
- package/README.md +2 -0
- package/dist/client/index.d.ts +9 -3
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +20 -0
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/component.d.ts +48 -4
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/lib.d.ts +1 -1
- package/dist/component/lib.d.ts.map +1 -1
- package/dist/component/lib.js +1 -1
- package/dist/component/lib.js.map +1 -1
- package/dist/component/queue.d.ts +37 -6
- package/dist/component/queue.d.ts.map +1 -1
- package/dist/component/queue.js +211 -10
- package/dist/component/queue.js.map +1 -1
- package/dist/component/schema.d.ts +39 -31
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +7 -4
- package/dist/component/schema.js.map +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +21 -0
- package/src/component/_generated/component.ts +66 -4
- package/src/component/lib.test.ts +175 -0
- package/src/component/lib.ts +3 -0
- package/src/component/queue.ts +236 -10
- package/src/component/schema.ts +19 -12
|
@@ -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, {
|
package/src/component/lib.ts
CHANGED
|
@@ -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,
|
package/src/component/queue.ts
CHANGED
|
@@ -65,6 +65,10 @@ const bridgeRuntimeConfigValidator = v.object({
|
|
|
65
65
|
serviceKeySecretRef: v.union(v.null(), v.string()),
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
+
const messageRuntimeConfigValidator = v.object({
|
|
69
|
+
systemPrompt: v.optional(v.string()),
|
|
70
|
+
});
|
|
71
|
+
|
|
68
72
|
const globalSkillStatusValidator = v.union(v.literal("active"), v.literal("disabled"));
|
|
69
73
|
const globalSkillReleaseChannelValidator = v.union(v.literal("stable"), v.literal("canary"));
|
|
70
74
|
const globalSkillModuleFormatValidator = v.union(v.literal("esm"), v.literal("cjs"));
|
|
@@ -86,6 +90,11 @@ const BRIDGE_SECRET_REFS = {
|
|
|
86
90
|
appKey: "agent-bridge.appKey",
|
|
87
91
|
} as const;
|
|
88
92
|
|
|
93
|
+
const RUNTIME_CONFIG_KEYS = {
|
|
94
|
+
provider: "provider",
|
|
95
|
+
message: "message",
|
|
96
|
+
} as const;
|
|
97
|
+
|
|
89
98
|
export const enqueueMessage = mutation({
|
|
90
99
|
args: {
|
|
91
100
|
conversationId: v.string(),
|
|
@@ -100,6 +109,10 @@ export const enqueueMessage = mutation({
|
|
|
100
109
|
returns: v.id("messageQueue"),
|
|
101
110
|
handler: async (ctx, args) => {
|
|
102
111
|
const nowMs = args.nowMs ?? Date.now();
|
|
112
|
+
const messageRuntimeConfigRow = await ctx.db
|
|
113
|
+
.query("runtimeConfig")
|
|
114
|
+
.withIndex("by_key", (q) => q.eq("key", RUNTIME_CONFIG_KEYS.message))
|
|
115
|
+
.unique();
|
|
103
116
|
const profile = await ctx.db
|
|
104
117
|
.query("agentProfiles")
|
|
105
118
|
.withIndex("by_agentKey", (q) => q.eq("agentKey", args.agentKey))
|
|
@@ -126,6 +139,10 @@ export const enqueueMessage = mutation({
|
|
|
126
139
|
|
|
127
140
|
const payload = {
|
|
128
141
|
...args.payload,
|
|
142
|
+
messageText: appendSystemPromptToMessage(
|
|
143
|
+
args.payload.messageText,
|
|
144
|
+
messageRuntimeConfigRow?.messageConfig?.systemPrompt,
|
|
145
|
+
),
|
|
129
146
|
providerUserId: providerUserIdStr,
|
|
130
147
|
metadata: {
|
|
131
148
|
...(args.payload.metadata ?? {}),
|
|
@@ -252,9 +269,9 @@ export const upsertAgentProfile = mutation({
|
|
|
252
269
|
agentKey: v.string(),
|
|
253
270
|
providerUserId: v.optional(v.string()),
|
|
254
271
|
version: v.string(),
|
|
255
|
-
soulMd: v.string(),
|
|
272
|
+
soulMd: v.optional(v.string()),
|
|
256
273
|
clientMd: v.optional(v.string()),
|
|
257
|
-
skills: v.array(v.string()),
|
|
274
|
+
skills: v.optional(v.array(v.string())),
|
|
258
275
|
secretsRef: v.array(v.string()),
|
|
259
276
|
bridgeConfig: v.optional(bridgeProfileConfigValidator),
|
|
260
277
|
enabled: v.boolean(),
|
|
@@ -278,6 +295,85 @@ export const upsertAgentProfile = mutation({
|
|
|
278
295
|
},
|
|
279
296
|
});
|
|
280
297
|
|
|
298
|
+
export const clearDeprecatedAgentProfileFields = mutation({
|
|
299
|
+
args: {
|
|
300
|
+
dryRun: v.optional(v.boolean()),
|
|
301
|
+
},
|
|
302
|
+
returns: v.object({
|
|
303
|
+
dryRun: v.boolean(),
|
|
304
|
+
scanned: v.number(),
|
|
305
|
+
updated: v.number(),
|
|
306
|
+
unchanged: v.number(),
|
|
307
|
+
clearedProviderUserId: v.number(),
|
|
308
|
+
clearedSoulMd: v.number(),
|
|
309
|
+
clearedClientMd: v.number(),
|
|
310
|
+
clearedSkills: v.number(),
|
|
311
|
+
updatedAgentKeys: v.array(v.string()),
|
|
312
|
+
}),
|
|
313
|
+
handler: async (ctx, args) => {
|
|
314
|
+
const profiles = await ctx.db.query("agentProfiles").collect();
|
|
315
|
+
const dryRun = args.dryRun ?? false;
|
|
316
|
+
|
|
317
|
+
let updated = 0;
|
|
318
|
+
let clearedProviderUserId = 0;
|
|
319
|
+
let clearedSoulMd = 0;
|
|
320
|
+
let clearedClientMd = 0;
|
|
321
|
+
let clearedSkills = 0;
|
|
322
|
+
const updatedAgentKeys: Array<string> = [];
|
|
323
|
+
|
|
324
|
+
for (const profile of profiles) {
|
|
325
|
+
const patch: {
|
|
326
|
+
providerUserId?: undefined;
|
|
327
|
+
soulMd?: undefined;
|
|
328
|
+
clientMd?: undefined;
|
|
329
|
+
skills?: undefined;
|
|
330
|
+
} = {};
|
|
331
|
+
let shouldPatch = false;
|
|
332
|
+
|
|
333
|
+
if (profile.providerUserId !== undefined) {
|
|
334
|
+
patch.providerUserId = undefined;
|
|
335
|
+
clearedProviderUserId += 1;
|
|
336
|
+
shouldPatch = true;
|
|
337
|
+
}
|
|
338
|
+
if (profile.soulMd !== undefined) {
|
|
339
|
+
patch.soulMd = undefined;
|
|
340
|
+
clearedSoulMd += 1;
|
|
341
|
+
shouldPatch = true;
|
|
342
|
+
}
|
|
343
|
+
if (profile.clientMd !== undefined) {
|
|
344
|
+
patch.clientMd = undefined;
|
|
345
|
+
clearedClientMd += 1;
|
|
346
|
+
shouldPatch = true;
|
|
347
|
+
}
|
|
348
|
+
if (profile.skills !== undefined) {
|
|
349
|
+
patch.skills = undefined;
|
|
350
|
+
clearedSkills += 1;
|
|
351
|
+
shouldPatch = true;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (!shouldPatch) continue;
|
|
355
|
+
|
|
356
|
+
updated += 1;
|
|
357
|
+
updatedAgentKeys.push(profile.agentKey);
|
|
358
|
+
if (!dryRun) {
|
|
359
|
+
await ctx.db.patch(profile._id, patch);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return {
|
|
364
|
+
dryRun,
|
|
365
|
+
scanned: profiles.length,
|
|
366
|
+
updated,
|
|
367
|
+
unchanged: profiles.length - updated,
|
|
368
|
+
clearedProviderUserId,
|
|
369
|
+
clearedSoulMd,
|
|
370
|
+
clearedClientMd,
|
|
371
|
+
clearedSkills,
|
|
372
|
+
updatedAgentKeys,
|
|
373
|
+
};
|
|
374
|
+
},
|
|
375
|
+
});
|
|
376
|
+
|
|
281
377
|
export const importPlaintextSecret = mutation({
|
|
282
378
|
args: {
|
|
283
379
|
secretRef: v.string(),
|
|
@@ -378,9 +474,9 @@ export const getProviderRuntimeConfig = internalQuery({
|
|
|
378
474
|
handler: async (ctx) => {
|
|
379
475
|
const row = await ctx.db
|
|
380
476
|
.query("runtimeConfig")
|
|
381
|
-
.withIndex("by_key", (q) => q.eq("key",
|
|
477
|
+
.withIndex("by_key", (q) => q.eq("key", RUNTIME_CONFIG_KEYS.provider))
|
|
382
478
|
.unique();
|
|
383
|
-
if (!row) {
|
|
479
|
+
if (!row?.providerConfig) {
|
|
384
480
|
return null;
|
|
385
481
|
}
|
|
386
482
|
return row.providerConfig;
|
|
@@ -397,11 +493,11 @@ export const upsertProviderRuntimeConfig = internalMutation({
|
|
|
397
493
|
const nowMs = args.nowMs ?? Date.now();
|
|
398
494
|
const existing = await ctx.db
|
|
399
495
|
.query("runtimeConfig")
|
|
400
|
-
.withIndex("by_key", (q) => q.eq("key",
|
|
496
|
+
.withIndex("by_key", (q) => q.eq("key", RUNTIME_CONFIG_KEYS.provider))
|
|
401
497
|
.unique();
|
|
402
498
|
if (!existing) {
|
|
403
499
|
await ctx.db.insert("runtimeConfig", {
|
|
404
|
-
key:
|
|
500
|
+
key: RUNTIME_CONFIG_KEYS.provider,
|
|
405
501
|
providerConfig: args.providerConfig,
|
|
406
502
|
updatedAt: nowMs,
|
|
407
503
|
});
|
|
@@ -421,9 +517,9 @@ export const providerRuntimeConfig = query({
|
|
|
421
517
|
handler: async (ctx) => {
|
|
422
518
|
const row = await ctx.db
|
|
423
519
|
.query("runtimeConfig")
|
|
424
|
-
.withIndex("by_key", (q) => q.eq("key",
|
|
520
|
+
.withIndex("by_key", (q) => q.eq("key", RUNTIME_CONFIG_KEYS.provider))
|
|
425
521
|
.unique();
|
|
426
|
-
if (!row) {
|
|
522
|
+
if (!row?.providerConfig) {
|
|
427
523
|
return null;
|
|
428
524
|
}
|
|
429
525
|
return row.providerConfig;
|
|
@@ -440,11 +536,11 @@ export const setProviderRuntimeConfig = mutation({
|
|
|
440
536
|
const nowMs = args.nowMs ?? Date.now();
|
|
441
537
|
const existing = await ctx.db
|
|
442
538
|
.query("runtimeConfig")
|
|
443
|
-
.withIndex("by_key", (q) => q.eq("key",
|
|
539
|
+
.withIndex("by_key", (q) => q.eq("key", RUNTIME_CONFIG_KEYS.provider))
|
|
444
540
|
.unique();
|
|
445
541
|
if (!existing) {
|
|
446
542
|
await ctx.db.insert("runtimeConfig", {
|
|
447
|
-
key:
|
|
543
|
+
key: RUNTIME_CONFIG_KEYS.provider,
|
|
448
544
|
providerConfig: args.providerConfig,
|
|
449
545
|
updatedAt: nowMs,
|
|
450
546
|
});
|
|
@@ -458,6 +554,106 @@ export const setProviderRuntimeConfig = mutation({
|
|
|
458
554
|
},
|
|
459
555
|
});
|
|
460
556
|
|
|
557
|
+
export const getMessageRuntimeConfig = internalQuery({
|
|
558
|
+
args: {},
|
|
559
|
+
returns: v.union(v.null(), messageRuntimeConfigValidator),
|
|
560
|
+
handler: async (ctx) => {
|
|
561
|
+
const row = await ctx.db
|
|
562
|
+
.query("runtimeConfig")
|
|
563
|
+
.withIndex("by_key", (q) => q.eq("key", RUNTIME_CONFIG_KEYS.message))
|
|
564
|
+
.unique();
|
|
565
|
+
if (!row?.messageConfig) {
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
return row.messageConfig;
|
|
569
|
+
},
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
export const upsertMessageRuntimeConfig = internalMutation({
|
|
573
|
+
args: {
|
|
574
|
+
messageConfig: messageRuntimeConfigValidator,
|
|
575
|
+
nowMs: v.optional(v.number()),
|
|
576
|
+
},
|
|
577
|
+
returns: v.null(),
|
|
578
|
+
handler: async (ctx, args) => {
|
|
579
|
+
const nowMs = args.nowMs ?? Date.now();
|
|
580
|
+
const normalizedMessageConfig = normalizeMessageRuntimeConfig(args.messageConfig);
|
|
581
|
+
const existing = await ctx.db
|
|
582
|
+
.query("runtimeConfig")
|
|
583
|
+
.withIndex("by_key", (q) => q.eq("key", RUNTIME_CONFIG_KEYS.message))
|
|
584
|
+
.unique();
|
|
585
|
+
if (normalizedMessageConfig === null) {
|
|
586
|
+
if (existing) {
|
|
587
|
+
await ctx.db.delete(existing._id);
|
|
588
|
+
}
|
|
589
|
+
return null;
|
|
590
|
+
}
|
|
591
|
+
if (!existing) {
|
|
592
|
+
await ctx.db.insert("runtimeConfig", {
|
|
593
|
+
key: RUNTIME_CONFIG_KEYS.message,
|
|
594
|
+
messageConfig: normalizedMessageConfig,
|
|
595
|
+
updatedAt: nowMs,
|
|
596
|
+
});
|
|
597
|
+
return null;
|
|
598
|
+
}
|
|
599
|
+
await ctx.db.patch(existing._id, {
|
|
600
|
+
messageConfig: normalizedMessageConfig,
|
|
601
|
+
updatedAt: nowMs,
|
|
602
|
+
});
|
|
603
|
+
return null;
|
|
604
|
+
},
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
export const messageRuntimeConfig = query({
|
|
608
|
+
args: {},
|
|
609
|
+
returns: v.union(v.null(), messageRuntimeConfigValidator),
|
|
610
|
+
handler: async (ctx) => {
|
|
611
|
+
const row = await ctx.db
|
|
612
|
+
.query("runtimeConfig")
|
|
613
|
+
.withIndex("by_key", (q) => q.eq("key", RUNTIME_CONFIG_KEYS.message))
|
|
614
|
+
.unique();
|
|
615
|
+
if (!row?.messageConfig) {
|
|
616
|
+
return null;
|
|
617
|
+
}
|
|
618
|
+
return row.messageConfig;
|
|
619
|
+
},
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
export const setMessageRuntimeConfig = mutation({
|
|
623
|
+
args: {
|
|
624
|
+
messageConfig: messageRuntimeConfigValidator,
|
|
625
|
+
nowMs: v.optional(v.number()),
|
|
626
|
+
},
|
|
627
|
+
returns: v.null(),
|
|
628
|
+
handler: async (ctx, args) => {
|
|
629
|
+
const nowMs = args.nowMs ?? Date.now();
|
|
630
|
+
const normalizedMessageConfig = normalizeMessageRuntimeConfig(args.messageConfig);
|
|
631
|
+
const existing = await ctx.db
|
|
632
|
+
.query("runtimeConfig")
|
|
633
|
+
.withIndex("by_key", (q) => q.eq("key", RUNTIME_CONFIG_KEYS.message))
|
|
634
|
+
.unique();
|
|
635
|
+
if (normalizedMessageConfig === null) {
|
|
636
|
+
if (existing) {
|
|
637
|
+
await ctx.db.delete(existing._id);
|
|
638
|
+
}
|
|
639
|
+
return null;
|
|
640
|
+
}
|
|
641
|
+
if (!existing) {
|
|
642
|
+
await ctx.db.insert("runtimeConfig", {
|
|
643
|
+
key: RUNTIME_CONFIG_KEYS.message,
|
|
644
|
+
messageConfig: normalizedMessageConfig,
|
|
645
|
+
updatedAt: nowMs,
|
|
646
|
+
});
|
|
647
|
+
return null;
|
|
648
|
+
}
|
|
649
|
+
await ctx.db.patch(existing._id, {
|
|
650
|
+
messageConfig: normalizedMessageConfig,
|
|
651
|
+
updatedAt: nowMs,
|
|
652
|
+
});
|
|
653
|
+
return null;
|
|
654
|
+
},
|
|
655
|
+
});
|
|
656
|
+
|
|
461
657
|
export const deployGlobalSkill = mutation({
|
|
462
658
|
args: {
|
|
463
659
|
slug: v.string(),
|
|
@@ -2041,6 +2237,36 @@ async function resolveBridgeRuntimeConfig(
|
|
|
2041
2237
|
};
|
|
2042
2238
|
}
|
|
2043
2239
|
|
|
2240
|
+
function appendSystemPromptToMessage(messageText: string, systemPrompt?: string): string {
|
|
2241
|
+
const normalizedSystemPrompt = normalizeSystemPrompt(systemPrompt);
|
|
2242
|
+
if (normalizedSystemPrompt === null) {
|
|
2243
|
+
return messageText;
|
|
2244
|
+
}
|
|
2245
|
+
const normalizedMessageText = messageText.trimEnd();
|
|
2246
|
+
if (normalizedMessageText.length === 0) {
|
|
2247
|
+
return normalizedSystemPrompt;
|
|
2248
|
+
}
|
|
2249
|
+
return `${normalizedMessageText}\n\n${normalizedSystemPrompt}`;
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
function normalizeMessageRuntimeConfig(
|
|
2253
|
+
messageConfig: { systemPrompt?: string } | null | undefined,
|
|
2254
|
+
): { systemPrompt?: string } | null {
|
|
2255
|
+
const systemPrompt = normalizeSystemPrompt(messageConfig?.systemPrompt);
|
|
2256
|
+
if (systemPrompt === null) {
|
|
2257
|
+
return null;
|
|
2258
|
+
}
|
|
2259
|
+
return { systemPrompt };
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
function normalizeSystemPrompt(systemPrompt?: string | null): string | null {
|
|
2263
|
+
if (typeof systemPrompt !== "string") {
|
|
2264
|
+
return null;
|
|
2265
|
+
}
|
|
2266
|
+
const normalizedSystemPrompt = systemPrompt.trim();
|
|
2267
|
+
return normalizedSystemPrompt.length > 0 ? normalizedSystemPrompt : null;
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2044
2270
|
function getBridgeSecretRefsForProfile(
|
|
2045
2271
|
agentKey: string,
|
|
2046
2272
|
bridgeConfig:
|
package/src/component/schema.ts
CHANGED
|
@@ -6,9 +6,9 @@ export default defineSchema({
|
|
|
6
6
|
agentKey: v.string(),
|
|
7
7
|
providerUserId: v.optional(v.string()),
|
|
8
8
|
version: v.string(),
|
|
9
|
-
soulMd: v.string(),
|
|
9
|
+
soulMd: v.optional(v.string()),
|
|
10
10
|
clientMd: v.optional(v.string()),
|
|
11
|
-
skills: v.array(v.string()),
|
|
11
|
+
skills: v.optional(v.array(v.string())),
|
|
12
12
|
secretsRef: v.array(v.string()),
|
|
13
13
|
bridgeConfig: v.optional(
|
|
14
14
|
v.object({
|
|
@@ -134,16 +134,23 @@ export default defineSchema({
|
|
|
134
134
|
|
|
135
135
|
runtimeConfig: defineTable({
|
|
136
136
|
key: v.string(),
|
|
137
|
-
providerConfig: v.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
137
|
+
providerConfig: v.optional(
|
|
138
|
+
v.object({
|
|
139
|
+
kind: v.union(v.literal("fly"), v.literal("runpod"), v.literal("ecs")),
|
|
140
|
+
appName: v.string(),
|
|
141
|
+
organizationSlug: v.string(),
|
|
142
|
+
image: v.string(),
|
|
143
|
+
region: v.string(),
|
|
144
|
+
volumeName: v.string(),
|
|
145
|
+
volumePath: v.string(),
|
|
146
|
+
volumeSizeGb: v.number(),
|
|
147
|
+
}),
|
|
148
|
+
),
|
|
149
|
+
messageConfig: v.optional(
|
|
150
|
+
v.object({
|
|
151
|
+
systemPrompt: v.optional(v.string()),
|
|
152
|
+
}),
|
|
153
|
+
),
|
|
147
154
|
updatedAt: v.number(),
|
|
148
155
|
}).index("by_key", ["key"]),
|
|
149
156
|
|