@okrlinkhub/agent-bridge 0.1.0 → 2.0.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 +96 -127
- package/dist/cli/init.d.ts +3 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +100 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/client/index.d.ts +50 -173
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +129 -263
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +4 -4
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/component.d.ts +66 -162
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/agentBridgeUtils.d.ts +8 -0
- package/dist/component/agentBridgeUtils.d.ts.map +1 -0
- package/dist/component/agentBridgeUtils.js +33 -0
- package/dist/component/agentBridgeUtils.js.map +1 -0
- package/dist/component/agents.d.ts +27 -0
- package/dist/component/agents.d.ts.map +1 -0
- package/dist/component/agents.js +94 -0
- package/dist/component/agents.js.map +1 -0
- package/dist/component/gateway.d.ts +30 -44
- package/dist/component/gateway.d.ts.map +1 -1
- package/dist/component/gateway.js +127 -132
- package/dist/component/gateway.js.map +1 -1
- package/dist/component/permissions.d.ts +30 -84
- package/dist/component/permissions.d.ts.map +1 -1
- package/dist/component/permissions.js +80 -203
- package/dist/component/permissions.js.map +1 -1
- package/dist/component/schema.d.ts +55 -153
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +30 -80
- package/dist/component/schema.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +2 -3
- package/dist/react/index.js.map +1 -1
- package/package.json +7 -3
- package/src/cli/init.ts +116 -0
- package/src/client/index.ts +228 -389
- package/src/component/_generated/api.ts +4 -4
- package/src/component/_generated/component.ts +79 -195
- package/src/component/agentBridgeUtils.ts +52 -0
- package/src/component/agents.ts +106 -0
- package/src/component/gateway.ts +149 -163
- package/src/component/permissions.ts +89 -259
- package/src/component/schema.ts +31 -96
- package/src/react/index.ts +5 -6
- package/dist/component/provisioning.d.ts +0 -87
- package/dist/component/provisioning.d.ts.map +0 -1
- package/dist/component/provisioning.js +0 -343
- package/dist/component/provisioning.js.map +0 -1
- package/dist/component/registry.d.ts +0 -46
- package/dist/component/registry.d.ts.map +0 -1
- package/dist/component/registry.js +0 -121
- package/dist/component/registry.js.map +0 -1
- package/src/component/provisioning.ts +0 -402
- package/src/component/registry.ts +0 -152
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import type * as agentBridgeUtils from "../agentBridgeUtils.js";
|
|
12
|
+
import type * as agents from "../agents.js";
|
|
11
13
|
import type * as gateway from "../gateway.js";
|
|
12
14
|
import type * as permissions from "../permissions.js";
|
|
13
|
-
import type * as provisioning from "../provisioning.js";
|
|
14
|
-
import type * as registry from "../registry.js";
|
|
15
15
|
|
|
16
16
|
import type {
|
|
17
17
|
ApiFromModules,
|
|
@@ -21,10 +21,10 @@ import type {
|
|
|
21
21
|
import { anyApi, componentsGeneric } from "convex/server";
|
|
22
22
|
|
|
23
23
|
const fullApi: ApiFromModules<{
|
|
24
|
+
agentBridgeUtils: typeof agentBridgeUtils;
|
|
25
|
+
agents: typeof agents;
|
|
24
26
|
gateway: typeof gateway;
|
|
25
27
|
permissions: typeof permissions;
|
|
26
|
-
provisioning: typeof provisioning;
|
|
27
|
-
registry: typeof registry;
|
|
28
28
|
}> = anyApi as any;
|
|
29
29
|
|
|
30
30
|
/**
|
|
@@ -23,258 +23,142 @@ import type { FunctionReference } from "convex/server";
|
|
|
23
23
|
*/
|
|
24
24
|
export type ComponentApi<Name extends string | undefined = string | undefined> =
|
|
25
25
|
{
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"mutation",
|
|
29
|
-
"internal",
|
|
30
|
-
{ appName: string; functionName: string; instanceToken: string },
|
|
31
|
-
| {
|
|
32
|
-
agentId: string;
|
|
33
|
-
appName: string;
|
|
34
|
-
authorized: true;
|
|
35
|
-
functionHandle: string;
|
|
36
|
-
functionType: "query" | "mutation" | "action";
|
|
37
|
-
}
|
|
38
|
-
| {
|
|
39
|
-
agentId?: string;
|
|
40
|
-
authorized: false;
|
|
41
|
-
error: string;
|
|
42
|
-
matchedPattern?: string;
|
|
43
|
-
matchedPermission?: "allow" | "deny" | "rate_limited";
|
|
44
|
-
statusCode: number;
|
|
45
|
-
},
|
|
46
|
-
Name
|
|
47
|
-
>;
|
|
48
|
-
logAccess: FunctionReference<
|
|
49
|
-
"mutation",
|
|
50
|
-
"internal",
|
|
51
|
-
{
|
|
52
|
-
agentId: string;
|
|
53
|
-
appName: string;
|
|
54
|
-
durationMs?: number;
|
|
55
|
-
errorMessage?: string;
|
|
56
|
-
functionCalled: string;
|
|
57
|
-
permission: string;
|
|
58
|
-
},
|
|
59
|
-
null,
|
|
60
|
-
Name
|
|
61
|
-
>;
|
|
62
|
-
queryAccessLog: FunctionReference<
|
|
63
|
-
"query",
|
|
64
|
-
"internal",
|
|
65
|
-
{ agentId?: string; appName?: string; limit?: number },
|
|
66
|
-
Array<{
|
|
67
|
-
agentId: string;
|
|
68
|
-
appName: string;
|
|
69
|
-
durationMs?: number;
|
|
70
|
-
errorMessage?: string;
|
|
71
|
-
functionCalled: string;
|
|
72
|
-
permission: string;
|
|
73
|
-
timestamp: number;
|
|
74
|
-
}>,
|
|
75
|
-
Name
|
|
76
|
-
>;
|
|
77
|
-
};
|
|
78
|
-
permissions: {
|
|
79
|
-
checkPermission: FunctionReference<
|
|
80
|
-
"query",
|
|
81
|
-
"internal",
|
|
82
|
-
{ agentId: string; appName: string; functionName: string },
|
|
83
|
-
{
|
|
84
|
-
matchedPattern?: string;
|
|
85
|
-
permission: "allow" | "deny" | "rate_limited";
|
|
86
|
-
rateLimitConfig?: { requestsPerHour: number; tokenBudget: number };
|
|
87
|
-
},
|
|
88
|
-
Name
|
|
89
|
-
>;
|
|
90
|
-
clearPermissions: FunctionReference<
|
|
26
|
+
agents: {
|
|
27
|
+
createAgent: FunctionReference<
|
|
91
28
|
"mutation",
|
|
92
29
|
"internal",
|
|
93
|
-
{
|
|
94
|
-
|
|
30
|
+
{ apiKey: string; enabled?: boolean; name: string; rateLimit?: number },
|
|
31
|
+
{ agentId: string },
|
|
95
32
|
Name
|
|
96
33
|
>;
|
|
97
|
-
|
|
98
|
-
"query",
|
|
99
|
-
"internal",
|
|
100
|
-
{ agentId: string; appName: string; functionName: string },
|
|
101
|
-
{
|
|
102
|
-
bestMatch?: {
|
|
103
|
-
functionPattern: string;
|
|
104
|
-
permission: "allow" | "deny" | "rate_limited";
|
|
105
|
-
specificity: number;
|
|
106
|
-
};
|
|
107
|
-
functionName: string;
|
|
108
|
-
matches: Array<{
|
|
109
|
-
functionPattern: string;
|
|
110
|
-
permission: "allow" | "deny" | "rate_limited";
|
|
111
|
-
specificity: number;
|
|
112
|
-
}>;
|
|
113
|
-
permissions: Array<{
|
|
114
|
-
functionPattern: string;
|
|
115
|
-
permission: "allow" | "deny" | "rate_limited";
|
|
116
|
-
specificity: number;
|
|
117
|
-
}>;
|
|
118
|
-
},
|
|
119
|
-
Name
|
|
120
|
-
>;
|
|
121
|
-
listPermissions: FunctionReference<
|
|
34
|
+
listAgents: FunctionReference<
|
|
122
35
|
"query",
|
|
123
36
|
"internal",
|
|
124
|
-
{
|
|
37
|
+
{},
|
|
125
38
|
Array<{
|
|
39
|
+
_id: string;
|
|
126
40
|
createdAt: number;
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
41
|
+
enabled: boolean;
|
|
42
|
+
lastUsed?: number;
|
|
43
|
+
name: string;
|
|
44
|
+
rateLimit: number;
|
|
131
45
|
}>,
|
|
132
46
|
Name
|
|
133
47
|
>;
|
|
134
|
-
|
|
48
|
+
rotateApiKey: FunctionReference<
|
|
135
49
|
"mutation",
|
|
136
50
|
"internal",
|
|
137
|
-
{ agentId: string;
|
|
138
|
-
|
|
51
|
+
{ agentId: string; newApiKey: string },
|
|
52
|
+
null,
|
|
139
53
|
Name
|
|
140
54
|
>;
|
|
141
|
-
|
|
55
|
+
updateAgent: FunctionReference<
|
|
142
56
|
"mutation",
|
|
143
57
|
"internal",
|
|
144
58
|
{
|
|
145
59
|
agentId: string;
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
permission: "allow" | "deny" | "rate_limited";
|
|
150
|
-
rateLimitConfig?: { requestsPerHour: number; tokenBudget: number };
|
|
60
|
+
enabled?: boolean;
|
|
61
|
+
name?: string;
|
|
62
|
+
rateLimit?: number;
|
|
151
63
|
},
|
|
152
|
-
|
|
64
|
+
null,
|
|
153
65
|
Name
|
|
154
66
|
>;
|
|
155
67
|
};
|
|
156
|
-
|
|
157
|
-
|
|
68
|
+
gateway: {
|
|
69
|
+
authorizeRequest: FunctionReference<
|
|
158
70
|
"mutation",
|
|
159
71
|
"internal",
|
|
160
|
-
{
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
72
|
+
{ apiKey: string; estimatedCost?: number; functionKey: string },
|
|
73
|
+
| { agentId: string; authorized: true }
|
|
74
|
+
| {
|
|
75
|
+
agentId?: string;
|
|
76
|
+
authorized: false;
|
|
77
|
+
error: string;
|
|
78
|
+
retryAfterSeconds?: number;
|
|
79
|
+
statusCode: number;
|
|
80
|
+
},
|
|
169
81
|
Name
|
|
170
82
|
>;
|
|
171
|
-
|
|
83
|
+
logAccess: FunctionReference<
|
|
172
84
|
"mutation",
|
|
173
85
|
"internal",
|
|
174
86
|
{
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
87
|
+
agentId: string;
|
|
88
|
+
args: any;
|
|
89
|
+
duration: number;
|
|
90
|
+
error?: string;
|
|
91
|
+
functionKey: string;
|
|
92
|
+
result?: any;
|
|
93
|
+
timestamp: number;
|
|
180
94
|
},
|
|
181
|
-
|
|
95
|
+
null,
|
|
182
96
|
Name
|
|
183
97
|
>;
|
|
184
|
-
|
|
98
|
+
queryAccessLog: FunctionReference<
|
|
185
99
|
"query",
|
|
186
100
|
"internal",
|
|
187
|
-
{
|
|
101
|
+
{ agentId?: string; functionKey?: string; limit?: number },
|
|
188
102
|
Array<{
|
|
103
|
+
_id: string;
|
|
189
104
|
agentId: string;
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
revokedBy?: string;
|
|
105
|
+
args: any;
|
|
106
|
+
duration: number;
|
|
107
|
+
error?: string;
|
|
108
|
+
functionKey: string;
|
|
109
|
+
result?: any;
|
|
110
|
+
timestamp: number;
|
|
197
111
|
}>,
|
|
198
112
|
Name
|
|
199
113
|
>;
|
|
200
|
-
provisionAgent: FunctionReference<
|
|
201
|
-
"mutation",
|
|
202
|
-
"internal",
|
|
203
|
-
{ appName: string; provisioningToken: string },
|
|
204
|
-
{
|
|
205
|
-
agentId: string;
|
|
206
|
-
appName: string;
|
|
207
|
-
expiresAt: number;
|
|
208
|
-
instanceToken: string;
|
|
209
|
-
message: string;
|
|
210
|
-
},
|
|
211
|
-
Name
|
|
212
|
-
>;
|
|
213
|
-
refreshInstanceToken: FunctionReference<
|
|
214
|
-
"mutation",
|
|
215
|
-
"internal",
|
|
216
|
-
{ agentId: string; appName: string; currentTokenHash: string },
|
|
217
|
-
{ expiresAt: number; instanceToken: string },
|
|
218
|
-
Name
|
|
219
|
-
>;
|
|
220
|
-
revokeAgent: FunctionReference<
|
|
221
|
-
"mutation",
|
|
222
|
-
"internal",
|
|
223
|
-
{ agentId: string; revokedBy: string },
|
|
224
|
-
boolean,
|
|
225
|
-
Name
|
|
226
|
-
>;
|
|
227
|
-
revokeAppInstance: FunctionReference<
|
|
228
|
-
"mutation",
|
|
229
|
-
"internal",
|
|
230
|
-
{ agentId: string; appName: string },
|
|
231
|
-
boolean,
|
|
232
|
-
Name
|
|
233
|
-
>;
|
|
234
114
|
};
|
|
235
|
-
|
|
236
|
-
|
|
115
|
+
permissions: {
|
|
116
|
+
listAgentPermissions: FunctionReference<
|
|
237
117
|
"query",
|
|
238
118
|
"internal",
|
|
239
|
-
{
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
}
|
|
119
|
+
{ agentId: string },
|
|
120
|
+
Array<{
|
|
121
|
+
functionPattern: string;
|
|
122
|
+
permission: "allow" | "deny" | "rate_limited";
|
|
123
|
+
rateLimitConfig?: { requestsPerHour: number; tokenBudget?: number };
|
|
124
|
+
updatedAt: number;
|
|
125
|
+
}>,
|
|
246
126
|
Name
|
|
247
127
|
>;
|
|
248
|
-
|
|
128
|
+
listFunctionOverrides: FunctionReference<
|
|
249
129
|
"query",
|
|
250
130
|
"internal",
|
|
251
|
-
{
|
|
252
|
-
Array<{
|
|
253
|
-
description?: string;
|
|
254
|
-
functionName: string;
|
|
255
|
-
functionType: "query" | "mutation" | "action";
|
|
256
|
-
registeredAt: number;
|
|
257
|
-
}>,
|
|
131
|
+
{},
|
|
132
|
+
Array<{ enabled: boolean; globalRateLimit?: number; key: string }>,
|
|
258
133
|
Name
|
|
259
134
|
>;
|
|
260
|
-
|
|
135
|
+
setAgentPermissions: FunctionReference<
|
|
261
136
|
"mutation",
|
|
262
137
|
"internal",
|
|
263
138
|
{
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
139
|
+
agentId: string;
|
|
140
|
+
availableFunctionKeys: Array<string>;
|
|
141
|
+
rules: Array<{
|
|
142
|
+
pattern: string;
|
|
143
|
+
permission: "allow" | "deny" | "rate_limited";
|
|
144
|
+
rateLimitConfig?: { requestsPerHour: number; tokenBudget?: number };
|
|
145
|
+
}>;
|
|
269
146
|
},
|
|
270
|
-
|
|
147
|
+
number,
|
|
271
148
|
Name
|
|
272
149
|
>;
|
|
273
|
-
|
|
150
|
+
setFunctionOverrides: FunctionReference<
|
|
274
151
|
"mutation",
|
|
275
152
|
"internal",
|
|
276
|
-
{
|
|
277
|
-
|
|
153
|
+
{
|
|
154
|
+
availableFunctionKeys: Array<string>;
|
|
155
|
+
overrides: Array<{
|
|
156
|
+
enabled: boolean;
|
|
157
|
+
globalRateLimit?: number;
|
|
158
|
+
key: string;
|
|
159
|
+
}>;
|
|
160
|
+
},
|
|
161
|
+
number,
|
|
278
162
|
Name
|
|
279
163
|
>;
|
|
280
164
|
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Doc } from "./_generated/dataModel.js";
|
|
2
|
+
|
|
3
|
+
export type PermissionType = "allow" | "deny" | "rate_limited";
|
|
4
|
+
|
|
5
|
+
export async function hashApiKey(apiKey: string): Promise<string> {
|
|
6
|
+
const encoder = new TextEncoder();
|
|
7
|
+
const data = encoder.encode(apiKey);
|
|
8
|
+
const hash = await crypto.subtle.digest("SHA-256", data);
|
|
9
|
+
return Array.from(new Uint8Array(hash))
|
|
10
|
+
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
11
|
+
.join("");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function matchesPattern(functionKey: string, pattern: string): boolean {
|
|
15
|
+
if (pattern === "*") {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
20
|
+
const regexPattern = "^" + escaped.replace(/\*/g, ".*") + "$";
|
|
21
|
+
return new RegExp(regexPattern).test(functionKey);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function patternSpecificity(pattern: string): number {
|
|
25
|
+
const wildcardIndex = pattern.indexOf("*");
|
|
26
|
+
if (wildcardIndex === -1) {
|
|
27
|
+
return pattern.length;
|
|
28
|
+
}
|
|
29
|
+
return wildcardIndex;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function findBestPermissionMatch(
|
|
33
|
+
functionKey: string,
|
|
34
|
+
permissions: Array<Doc<"agentPermissions">>,
|
|
35
|
+
): Doc<"agentPermissions"> | null {
|
|
36
|
+
const matches = permissions
|
|
37
|
+
.filter((permission) => matchesPattern(functionKey, permission.functionPattern))
|
|
38
|
+
.sort(
|
|
39
|
+
(a, b) =>
|
|
40
|
+
patternSpecificity(b.functionPattern) - patternSpecificity(a.functionPattern),
|
|
41
|
+
);
|
|
42
|
+
return matches[0] ?? null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function patternMatchesAvailableFunctions(
|
|
46
|
+
pattern: string,
|
|
47
|
+
availableFunctionKeys: string[],
|
|
48
|
+
): boolean {
|
|
49
|
+
return availableFunctionKeys.some((functionKey) =>
|
|
50
|
+
matchesPattern(functionKey, pattern),
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { v } from "convex/values";
|
|
2
|
+
import { mutation, query } from "./_generated/server.js";
|
|
3
|
+
import { hashApiKey } from "./agentBridgeUtils.js";
|
|
4
|
+
|
|
5
|
+
export const createAgent = mutation({
|
|
6
|
+
args: {
|
|
7
|
+
name: v.string(),
|
|
8
|
+
apiKey: v.string(),
|
|
9
|
+
enabled: v.optional(v.boolean()),
|
|
10
|
+
rateLimit: v.optional(v.number()),
|
|
11
|
+
},
|
|
12
|
+
returns: v.object({
|
|
13
|
+
agentId: v.id("agents"),
|
|
14
|
+
}),
|
|
15
|
+
handler: async (ctx, args) => {
|
|
16
|
+
const apiKeyHash = await hashApiKey(args.apiKey);
|
|
17
|
+
const existing = await ctx.db
|
|
18
|
+
.query("agents")
|
|
19
|
+
.withIndex("by_apiKeyHash", (q) => q.eq("apiKeyHash", apiKeyHash))
|
|
20
|
+
.unique();
|
|
21
|
+
|
|
22
|
+
if (existing) {
|
|
23
|
+
throw new Error("An agent with this API key already exists");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const agentId = await ctx.db.insert("agents", {
|
|
27
|
+
name: args.name,
|
|
28
|
+
apiKeyHash,
|
|
29
|
+
enabled: args.enabled ?? true,
|
|
30
|
+
rateLimit: args.rateLimit ?? 1000,
|
|
31
|
+
createdAt: Date.now(),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return { agentId };
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export const rotateApiKey = mutation({
|
|
39
|
+
args: {
|
|
40
|
+
agentId: v.id("agents"),
|
|
41
|
+
newApiKey: v.string(),
|
|
42
|
+
},
|
|
43
|
+
returns: v.null(),
|
|
44
|
+
handler: async (ctx, args) => {
|
|
45
|
+
const agent = await ctx.db.get(args.agentId);
|
|
46
|
+
if (!agent) {
|
|
47
|
+
throw new Error("Agent not found");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const newApiKeyHash = await hashApiKey(args.newApiKey);
|
|
51
|
+
await ctx.db.patch(args.agentId, {
|
|
52
|
+
apiKeyHash: newApiKeyHash,
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
return null;
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
export const updateAgent = mutation({
|
|
60
|
+
args: {
|
|
61
|
+
agentId: v.id("agents"),
|
|
62
|
+
name: v.optional(v.string()),
|
|
63
|
+
enabled: v.optional(v.boolean()),
|
|
64
|
+
rateLimit: v.optional(v.number()),
|
|
65
|
+
},
|
|
66
|
+
returns: v.null(),
|
|
67
|
+
handler: async (ctx, args) => {
|
|
68
|
+
const agent = await ctx.db.get(args.agentId);
|
|
69
|
+
if (!agent) {
|
|
70
|
+
throw new Error("Agent not found");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
await ctx.db.patch(args.agentId, {
|
|
74
|
+
name: args.name ?? agent.name,
|
|
75
|
+
enabled: args.enabled ?? agent.enabled,
|
|
76
|
+
rateLimit: args.rateLimit ?? agent.rateLimit,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return null;
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
export const listAgents = query({
|
|
84
|
+
args: {},
|
|
85
|
+
returns: v.array(
|
|
86
|
+
v.object({
|
|
87
|
+
_id: v.id("agents"),
|
|
88
|
+
name: v.string(),
|
|
89
|
+
enabled: v.boolean(),
|
|
90
|
+
rateLimit: v.number(),
|
|
91
|
+
lastUsed: v.optional(v.number()),
|
|
92
|
+
createdAt: v.number(),
|
|
93
|
+
}),
|
|
94
|
+
),
|
|
95
|
+
handler: async (ctx) => {
|
|
96
|
+
const agents = await ctx.db.query("agents").collect();
|
|
97
|
+
return agents.map((agent) => ({
|
|
98
|
+
_id: agent._id,
|
|
99
|
+
name: agent.name,
|
|
100
|
+
enabled: agent.enabled,
|
|
101
|
+
rateLimit: agent.rateLimit,
|
|
102
|
+
lastUsed: agent.lastUsed,
|
|
103
|
+
createdAt: agent.createdAt,
|
|
104
|
+
}));
|
|
105
|
+
},
|
|
106
|
+
});
|