@vantageos/agent-engine 0.1.0-alpha.5 → 0.1.0-alpha.7

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.
Files changed (43) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +154 -473
  3. package/dist/component/_generated/api.d.ts +31 -0
  4. package/dist/component/_generated/component.d.ts +346 -2
  5. package/dist/component/convex.config.js +18 -0
  6. package/dist/component/engine/agents.d.ts +10 -0
  7. package/dist/component/engine/agents.js +21 -0
  8. package/dist/component/engine/awaitEventTimeout.d.ts +13 -0
  9. package/dist/component/engine/awaitEventTimeout.js +81 -0
  10. package/dist/component/engine/delegation.d.ts +75 -0
  11. package/dist/component/engine/delegation.js +327 -0
  12. package/dist/component/engine/directory.d.ts +9 -0
  13. package/dist/component/engine/directory.js +45 -0
  14. package/dist/component/engine/durableJob.js +6 -6
  15. package/dist/component/engine/habits.d.ts +70 -0
  16. package/dist/component/engine/habits.js +218 -0
  17. package/dist/component/engine/mandates.d.ts +74 -0
  18. package/dist/component/engine/mandates.js +271 -0
  19. package/dist/component/engine/sandboxCallback.d.ts +36 -0
  20. package/dist/component/engine/sandboxCallback.js +259 -0
  21. package/dist/component/engine/sessions.d.ts +6 -2
  22. package/dist/component/engine/sessions.js +43 -7
  23. package/dist/component/engine/toolApprovals.js +1 -1
  24. package/dist/component/engine/vpConnection.d.ts +69 -0
  25. package/dist/component/engine/vpConnection.js +218 -0
  26. package/dist/component/engine/wakeup.d.ts +33 -0
  27. package/dist/component/engine/wakeup.js +228 -0
  28. package/dist/component/engine/workflows.d.ts +11 -0
  29. package/dist/component/engine/workflows.js +84 -0
  30. package/dist/component/schema.d.ts +365 -4
  31. package/dist/component/schema.js +345 -18
  32. package/dist/component/testFixtures/callerSteps.js +1 -1
  33. package/dist/component/testFixtures/delegationDemoWorkflow.d.ts +18 -0
  34. package/dist/component/testFixtures/delegationDemoWorkflow.js +75 -0
  35. package/dist/component/testFixtures/sandboxDemoWorkflow.d.ts +19 -0
  36. package/dist/component/testFixtures/sandboxDemoWorkflow.js +69 -0
  37. package/dist/component/testFixtures/vpTool.d.ts +4 -0
  38. package/dist/component/testFixtures/vpTool.js +25 -0
  39. package/dist/component/testFixtures/wakeupDemoWorkflow.d.ts +19 -0
  40. package/dist/component/testFixtures/wakeupDemoWorkflow.js +77 -0
  41. package/dist/component/testFixtures/wakeupWork.d.ts +8 -0
  42. package/dist/component/testFixtures/wakeupWork.js +21 -0
  43. package/package.json +17 -5
@@ -7,21 +7,49 @@
7
7
  * @module
8
8
  */
9
9
  import type * as engine_agents from "../engine/agents.js";
10
+ import type * as engine_awaitEventTimeout from "../engine/awaitEventTimeout.js";
11
+ import type * as engine_delegation from "../engine/delegation.js";
12
+ import type * as engine_directory from "../engine/directory.js";
10
13
  import type * as engine_durableJob from "../engine/durableJob.js";
14
+ import type * as engine_habits from "../engine/habits.js";
15
+ import type * as engine_mandates from "../engine/mandates.js";
11
16
  import type * as engine_resolvers from "../engine/resolvers.js";
17
+ import type * as engine_sandboxCallback from "../engine/sandboxCallback.js";
12
18
  import type * as engine_sessions from "../engine/sessions.js";
13
19
  import type * as engine_toolApprovals from "../engine/toolApprovals.js";
20
+ import type * as engine_vpConnection from "../engine/vpConnection.js";
21
+ import type * as engine_wakeup from "../engine/wakeup.js";
22
+ import type * as engine_workflows from "../engine/workflows.js";
14
23
  import type * as lib_auth from "../lib/auth.js";
15
24
  import type * as testFixtures_callerSteps from "../testFixtures/callerSteps.js";
25
+ import type * as testFixtures_delegationDemoWorkflow from "../testFixtures/delegationDemoWorkflow.js";
26
+ import type * as testFixtures_sandboxDemoWorkflow from "../testFixtures/sandboxDemoWorkflow.js";
27
+ import type * as testFixtures_vpTool from "../testFixtures/vpTool.js";
28
+ import type * as testFixtures_wakeupDemoWorkflow from "../testFixtures/wakeupDemoWorkflow.js";
29
+ import type * as testFixtures_wakeupWork from "../testFixtures/wakeupWork.js";
16
30
  import type { ApiFromModules, FilterApi, FunctionReference } from "convex/server";
17
31
  declare const fullApi: ApiFromModules<{
18
32
  "engine/agents": typeof engine_agents;
33
+ "engine/awaitEventTimeout": typeof engine_awaitEventTimeout;
34
+ "engine/delegation": typeof engine_delegation;
35
+ "engine/directory": typeof engine_directory;
19
36
  "engine/durableJob": typeof engine_durableJob;
37
+ "engine/habits": typeof engine_habits;
38
+ "engine/mandates": typeof engine_mandates;
20
39
  "engine/resolvers": typeof engine_resolvers;
40
+ "engine/sandboxCallback": typeof engine_sandboxCallback;
21
41
  "engine/sessions": typeof engine_sessions;
22
42
  "engine/toolApprovals": typeof engine_toolApprovals;
43
+ "engine/vpConnection": typeof engine_vpConnection;
44
+ "engine/wakeup": typeof engine_wakeup;
45
+ "engine/workflows": typeof engine_workflows;
23
46
  "lib/auth": typeof lib_auth;
24
47
  "testFixtures/callerSteps": typeof testFixtures_callerSteps;
48
+ "testFixtures/delegationDemoWorkflow": typeof testFixtures_delegationDemoWorkflow;
49
+ "testFixtures/sandboxDemoWorkflow": typeof testFixtures_sandboxDemoWorkflow;
50
+ "testFixtures/vpTool": typeof testFixtures_vpTool;
51
+ "testFixtures/wakeupDemoWorkflow": typeof testFixtures_wakeupDemoWorkflow;
52
+ "testFixtures/wakeupWork": typeof testFixtures_wakeupWork;
25
53
  }>;
26
54
  /**
27
55
  * A utility for referencing Convex functions in your app's public API.
@@ -46,5 +74,8 @@ export declare const components: {
46
74
  agentTurnPool: import("@convex-dev/workpool/_generated/component.js").ComponentApi<"agentTurnPool">;
47
75
  wakeupPool: import("@convex-dev/workpool/_generated/component.js").ComponentApi<"wakeupPool">;
48
76
  agent: import("@convex-dev/agent/_generated/component.js").ComponentApi<"agent">;
77
+ rateLimiter: import("@convex-dev/rate-limiter/_generated/component.js").ComponentApi<"rateLimiter">;
78
+ shardedCounter: import("@convex-dev/sharded-counter/_generated/component.js").ComponentApi<"shardedCounter">;
79
+ crons: import("@convex-dev/crons/_generated/component.js").ComponentApi<"crons">;
49
80
  };
50
81
  export {};
@@ -23,10 +23,15 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
23
23
  agents: {
24
24
  create: FunctionReference<"mutation", "internal", {
25
25
  createdBy: string;
26
+ description?: string;
26
27
  instructions: string;
28
+ maxInputTokensPerSession?: number | false;
29
+ maxSubagents?: number;
27
30
  model: string;
31
+ modelProvider?: "gateway" | "openrouter";
28
32
  name: string;
29
33
  orgId: string;
34
+ reasoningEffort?: "none" | "low" | "medium" | "high";
30
35
  }, string, Name>;
31
36
  get: FunctionReference<"query", "internal", {
32
37
  agentId: string;
@@ -36,14 +41,88 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
36
41
  _id: string;
37
42
  createdAt: number;
38
43
  createdBy: string;
44
+ description?: string;
39
45
  instructions: string;
46
+ maxInputTokensPerSession?: number | false;
47
+ maxSubagents?: number;
40
48
  model: string;
49
+ modelProvider?: "gateway" | "openrouter";
41
50
  name: string;
42
51
  orgId: string;
52
+ reasoningEffort?: "none" | "low" | "medium" | "high";
43
53
  status: "draft" | "live" | "archived";
44
54
  updatedAt: number;
45
55
  } | null, Name>;
46
56
  };
57
+ awaitEventTimeout: {
58
+ cancel: FunctionReference<"mutation", "internal", {
59
+ orgId: string;
60
+ timeoutRowId: string;
61
+ }, null, Name>;
62
+ schedule: FunctionReference<"mutation", "internal", {
63
+ awaitedEventName: string;
64
+ orgId: string;
65
+ sessionId: string;
66
+ timeoutMs: number;
67
+ }, string, Name>;
68
+ };
69
+ delegation: {
70
+ declareSubagent: FunctionReference<"mutation", "internal", {
71
+ childAgentId: string;
72
+ description?: string;
73
+ orgId: string;
74
+ parentAgentId: string;
75
+ toolName: string;
76
+ }, string, Name>;
77
+ delegateToSubagent: FunctionReference<"action", "internal", {
78
+ awaitedEventName: string;
79
+ cost: number;
80
+ orgId: string;
81
+ payload?: string;
82
+ reason: string;
83
+ scope: string;
84
+ subagentId: string;
85
+ workFunctionHandle: string;
86
+ workflowId: string;
87
+ }, string, Name>;
88
+ invokeAgentClone: FunctionReference<"action", "internal", {
89
+ agentId: string;
90
+ awaitedEventName: string;
91
+ cost: number;
92
+ orgId: string;
93
+ payload?: string;
94
+ reason: string;
95
+ scope: string;
96
+ viaAgentTool: boolean;
97
+ workFunctionHandle: string;
98
+ workflowId: string;
99
+ }, string, Name>;
100
+ listSubagents: FunctionReference<"query", "internal", {
101
+ orgId: string;
102
+ parentAgentId: string;
103
+ }, Array<{
104
+ _creationTime: number;
105
+ _id: string;
106
+ childAgentId: string;
107
+ createdAt: number;
108
+ description?: string;
109
+ enabled: boolean;
110
+ orgId: string;
111
+ parentAgentId: string;
112
+ toolName: string;
113
+ }>, Name>;
114
+ };
115
+ directory: {
116
+ listByOrg: FunctionReference<"query", "internal", {
117
+ orgId: string;
118
+ }, Array<{
119
+ _id: string;
120
+ createdAt: number;
121
+ model: string;
122
+ name: string;
123
+ status: "draft" | "live" | "archived";
124
+ }>, Name>;
125
+ };
47
126
  durableJob: {
48
127
  cancel: FunctionReference<"mutation", "internal", {
49
128
  jobId: string;
@@ -67,6 +146,140 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
67
146
  totalSteps: number;
68
147
  }, string, Name>;
69
148
  };
149
+ habits: {
150
+ create: FunctionReference<"mutation", "internal", {
151
+ agentId: string;
152
+ cronExpression: string;
153
+ name: string;
154
+ orgId: string;
155
+ prompt: string;
156
+ }, string, Name>;
157
+ disable: FunctionReference<"mutation", "internal", {
158
+ habitId: string;
159
+ orgId: string;
160
+ }, null, Name>;
161
+ enable: FunctionReference<"mutation", "internal", {
162
+ habitId: string;
163
+ orgId: string;
164
+ }, null, Name>;
165
+ get: FunctionReference<"query", "internal", {
166
+ habitId: string;
167
+ orgId: string;
168
+ }, {
169
+ _creationTime: number;
170
+ _id: string;
171
+ agentId: string;
172
+ createdAt: number;
173
+ cronExpression: string;
174
+ cronJobId?: string;
175
+ enabled: boolean;
176
+ lastRunAt?: number;
177
+ name: string;
178
+ orgId: string;
179
+ prompt: string;
180
+ updatedAt: number;
181
+ } | null, Name>;
182
+ listForAgent: FunctionReference<"query", "internal", {
183
+ agentId: string;
184
+ orgId: string;
185
+ }, Array<{
186
+ _creationTime: number;
187
+ _id: string;
188
+ agentId: string;
189
+ createdAt: number;
190
+ cronExpression: string;
191
+ cronJobId?: string;
192
+ enabled: boolean;
193
+ lastRunAt?: number;
194
+ name: string;
195
+ orgId: string;
196
+ prompt: string;
197
+ updatedAt: number;
198
+ }>, Name>;
199
+ listRuns: FunctionReference<"query", "internal", {
200
+ habitId: string;
201
+ orgId: string;
202
+ }, Array<{
203
+ _creationTime: number;
204
+ _id: string;
205
+ agentId: string;
206
+ habitId: string;
207
+ orgId: string;
208
+ ranAt: number;
209
+ }>, Name>;
210
+ updateSchedule: FunctionReference<"mutation", "internal", {
211
+ cronExpression?: string;
212
+ habitId: string;
213
+ name?: string;
214
+ orgId: string;
215
+ prompt?: string;
216
+ }, null, Name>;
217
+ };
218
+ mandates: {
219
+ get: FunctionReference<"query", "internal", {
220
+ agentId: string;
221
+ orgId: string;
222
+ scope: string;
223
+ }, {
224
+ _creationTime: number;
225
+ _id: string;
226
+ agentId: string;
227
+ capacity?: number;
228
+ createdAt: number;
229
+ kind: "token bucket" | "fixed window";
230
+ orgId: string;
231
+ period: number;
232
+ rate: number;
233
+ scope: string;
234
+ updatedAt: number;
235
+ } | null, Name>;
236
+ listApprovals: FunctionReference<"query", "internal", {
237
+ agentId?: string;
238
+ orgId: string;
239
+ }, Array<{
240
+ _creationTime: number;
241
+ _id: string;
242
+ agentId: string;
243
+ createdAt: number;
244
+ orgId: string;
245
+ reason: string;
246
+ requestedCost: number;
247
+ resolvedAt?: number;
248
+ resolvedBy?: string;
249
+ scope: string;
250
+ status: "pending" | "approved" | "denied";
251
+ }>, Name>;
252
+ resolveApproval: FunctionReference<"mutation", "internal", {
253
+ approvalId: string;
254
+ decision: "approved" | "denied";
255
+ orgId: string;
256
+ resolvedBy: string;
257
+ }, null, Name>;
258
+ set: FunctionReference<"mutation", "internal", {
259
+ agentId: string;
260
+ capacity?: number;
261
+ kind: "token bucket" | "fixed window";
262
+ orgId: string;
263
+ period: number;
264
+ rate: number;
265
+ scope: string;
266
+ }, string, Name>;
267
+ spend: FunctionReference<"mutation", "internal", {
268
+ agentId: string;
269
+ cost: number;
270
+ orgId: string;
271
+ reason: string;
272
+ scope: string;
273
+ }, {
274
+ approvalId?: string;
275
+ ok: boolean;
276
+ }, Name>;
277
+ usageCount: FunctionReference<"query", "internal", {
278
+ agentId: string;
279
+ orgId: string;
280
+ scope: string;
281
+ }, number, Name>;
282
+ };
70
283
  resolvers: {
71
284
  resolveManifest: FunctionReference<"query", "internal", {
72
285
  orgId: string;
@@ -82,6 +295,41 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
82
295
  }>;
83
296
  }, Name>;
84
297
  };
298
+ sandboxCallback: {
299
+ attachSandboxId: FunctionReference<"mutation", "internal", {
300
+ orgId: string;
301
+ sandboxId: string;
302
+ sandboxRunId: string;
303
+ }, null, Name>;
304
+ deadLetterMalformed: FunctionReference<"mutation", "internal", {
305
+ deliveryId: string;
306
+ orgId?: string;
307
+ rawBody: string;
308
+ reason: string;
309
+ }, null, Name>;
310
+ getStatus: FunctionReference<"query", "internal", {
311
+ orgId: string;
312
+ sandboxRunId: string;
313
+ }, {
314
+ resultSummary?: string;
315
+ status: "pending" | "completed" | "failed" | "timedOut";
316
+ }, Name>;
317
+ processCallback: FunctionReference<"mutation", "internal", {
318
+ deliveryId: string;
319
+ orgId: string;
320
+ resultSummary?: string;
321
+ sandboxRunId: string;
322
+ status: "completed" | "failed";
323
+ }, {
324
+ outcome: "woke" | "duplicate" | "dead-lettered";
325
+ }, Name>;
326
+ startRun: FunctionReference<"mutation", "internal", {
327
+ awaitedEventName: string;
328
+ orgId: string;
329
+ timeoutMs: number;
330
+ workflowId: string;
331
+ }, string, Name>;
332
+ };
85
333
  sessions: {
86
334
  appendReasoning: FunctionReference<"mutation", "internal", {
87
335
  chunk: string;
@@ -105,7 +353,7 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
105
353
  _creationTime: number;
106
354
  _id: string;
107
355
  createdAt: number;
108
- name: "session.started" | "turn.started" | "turn.reasoning" | "turn.toolCall.requested" | "turn.toolCall.completed" | "turn.toolCall.denied" | "turn.completed" | "tool.approval.requested" | "tool.approval.resolved";
356
+ name: "session.started" | "turn.started" | "turn.reasoning" | "turn.toolCall.requested" | "turn.toolCall.completed" | "turn.toolCall.denied" | "turn.completed" | "tool.approval.requested" | "tool.approval.resolved" | "sandbox.timeout";
109
357
  payload?: string;
110
358
  }>, Name>;
111
359
  requestToolCall: FunctionReference<"mutation", "internal", {
@@ -127,7 +375,10 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
127
375
  agentId: string;
128
376
  createdBy: string;
129
377
  orgId: string;
130
- }, string, Name>;
378
+ }, {
379
+ sessionId: string;
380
+ workflowId: string;
381
+ }, Name>;
131
382
  };
132
383
  toolApprovals: {
133
384
  respond: FunctionReference<"mutation", "internal", {
@@ -138,5 +389,98 @@ export type ComponentApi<Name extends string | undefined = string | undefined> =
138
389
  updatePolicy?: "always" | "once" | "never";
139
390
  }, null, Name>;
140
391
  };
392
+ vpConnection: {
393
+ get: FunctionReference<"query", "internal", {
394
+ agentId: string;
395
+ orgId: string;
396
+ }, {
397
+ _creationTime: number;
398
+ _id: string;
399
+ agentId: string;
400
+ createdAt: number;
401
+ memoryEnabled: boolean;
402
+ messagesEnabled: boolean;
403
+ notesEnabled: boolean;
404
+ orgId: string;
405
+ tasksEnabled: boolean;
406
+ updatedAt: number;
407
+ } | null, Name>;
408
+ getToggles: FunctionReference<"query", "internal", {
409
+ agentId: string;
410
+ orgId: string;
411
+ }, {
412
+ memoryEnabled: boolean;
413
+ messagesEnabled: boolean;
414
+ notesEnabled: boolean;
415
+ tasksEnabled: boolean;
416
+ }, Name>;
417
+ invokeVpTool: FunctionReference<"action", "internal", {
418
+ agentId: string;
419
+ argsJson: string;
420
+ orgId: string;
421
+ tool: "memory" | "tasks" | "messages" | "notes";
422
+ vpFunctionHandle: string;
423
+ }, null, Name>;
424
+ setToggles: FunctionReference<"mutation", "internal", {
425
+ agentId: string;
426
+ memoryEnabled?: boolean;
427
+ messagesEnabled?: boolean;
428
+ notesEnabled?: boolean;
429
+ orgId: string;
430
+ tasksEnabled?: boolean;
431
+ }, string, Name>;
432
+ };
433
+ wakeup: {
434
+ cancel: FunctionReference<"mutation", "internal", {
435
+ orgId: string;
436
+ wakeableWorkId: string;
437
+ }, null, Name>;
438
+ enqueue: FunctionReference<"action", "internal", {
439
+ agentId: string;
440
+ awaitedEventName: string;
441
+ cost: number;
442
+ orgId: string;
443
+ payload?: string;
444
+ reason: string;
445
+ scope: string;
446
+ workFunctionHandle: string;
447
+ workflowId: string;
448
+ }, string, Name>;
449
+ getStatus: FunctionReference<"query", "internal", {
450
+ orgId: string;
451
+ wakeableWorkId: string;
452
+ }, {
453
+ resultSummary?: string;
454
+ status: "pending" | "completed" | "failed" | "cancelled";
455
+ }, Name>;
456
+ };
457
+ };
458
+ testFixtures: {
459
+ delegationDemoWorkflow: {
460
+ start: FunctionReference<"mutation", "internal", {
461
+ awaitedEventName: string;
462
+ orgId: string;
463
+ }, {
464
+ workflowId: string;
465
+ }, Name>;
466
+ };
467
+ sandboxDemoWorkflow: {
468
+ start: FunctionReference<"mutation", "internal", {
469
+ awaitedEventName: string;
470
+ orgId: string;
471
+ }, {
472
+ resultId: string;
473
+ workflowId: string;
474
+ }, Name>;
475
+ };
476
+ wakeupDemoWorkflow: {
477
+ start: FunctionReference<"mutation", "internal", {
478
+ awaitedEventName: string;
479
+ orgId: string;
480
+ }, {
481
+ resultId: string;
482
+ workflowId: string;
483
+ }, Name>;
484
+ };
141
485
  };
142
486
  };
@@ -2,6 +2,9 @@ import { defineComponent } from "convex/server";
2
2
  import workflow from "@convex-dev/workflow/convex.config";
3
3
  import workpool from "@convex-dev/workpool/convex.config";
4
4
  import agent from "@convex-dev/agent/convex.config";
5
+ import rateLimiter from "@convex-dev/rate-limiter/convex.config";
6
+ import shardedCounter from "@convex-dev/sharded-counter/convex.config";
7
+ import crons from "@convex-dev/crons/convex.config";
5
8
  // @vantageos/agent-engine — Convex COMPONENT definition (pattern
6
9
  // `@convex-dev/*`, verified against the published shape of
7
10
  // `@convex-dev/workflow` — `defineComponent(name)` + a `convex.config.ts`
@@ -32,9 +35,24 @@ import agent from "@convex-dev/agent/convex.config";
32
35
  // awaitEventTimeouts, wakeableWork) is deliberately NOT yet re-hosted
33
36
  // here — porting those without a working component-level test harness
34
37
  // behind each of them would violate Day 128 (never ship unverified).
38
+ // Mandates (bounded, weighted spending authority per agent/org/scope) are
39
+ // hosted under this component boundary, using official `@convex-dev/*`
40
+ // libraries only -- no canary/alpha dependency for a guardrail:
41
+ // `rate-limiter` for the fails-closed spend gate itself, `sharded-counter`
42
+ // for the usage rollup. See component/engine/mandates.ts.
43
+ // Habits (a dynamic, per-agent/org cron schedule editable at runtime) are
44
+ // also hosted under this component boundary, ported byte-identical from the
45
+ // repo-root prototype (convex/habits.ts). `crons` is a sub-component of
46
+ // THIS component -- create/updateSchedule/enable/disable register or tear
47
+ // down a runtime cron job via `@convex-dev/crons` inside the SAME Convex
48
+ // mutation transaction that writes the `habits` row, so no habit schedule
49
+ // change ever requires a redeploy. See component/engine/habits.ts.
35
50
  const component = defineComponent("agentEngine");
36
51
  component.use(workflow);
37
52
  component.use(workpool, { name: "agentTurnPool" });
38
53
  component.use(workpool, { name: "wakeupPool" });
39
54
  component.use(agent);
55
+ component.use(rateLimiter);
56
+ component.use(shardedCounter);
57
+ component.use(crons);
40
58
  export default component;
@@ -1,4 +1,9 @@
1
1
  export declare const create: import("convex/server").RegisteredMutation<"public", {
2
+ description?: string | undefined;
3
+ reasoningEffort?: "none" | "low" | "medium" | "high" | undefined;
4
+ modelProvider?: "gateway" | "openrouter" | undefined;
5
+ maxSubagents?: number | undefined;
6
+ maxInputTokensPerSession?: number | false | undefined;
2
7
  name: string;
3
8
  orgId: string;
4
9
  instructions: string;
@@ -11,6 +16,11 @@ export declare const get: import("convex/server").RegisteredQuery<"public", {
11
16
  }, Promise<{
12
17
  _id: import("convex/values").GenericId<"agents">;
13
18
  _creationTime: number;
19
+ description?: string | undefined;
20
+ reasoningEffort?: "none" | "low" | "medium" | "high" | undefined;
21
+ modelProvider?: "gateway" | "openrouter" | undefined;
22
+ maxSubagents?: number | undefined;
23
+ maxInputTokensPerSession?: number | false | undefined;
14
24
  name: string;
15
25
  orgId: string;
16
26
  status: "draft" | "live" | "archived";
@@ -8,13 +8,21 @@ import { requireOrgId } from "../lib/auth.js";
8
8
  // `create`/`get`, no `update`/`list`/skills/connections — the full agent
9
9
  // aggregate CRUD stays out of this component boundary for this pass (see
10
10
  // component/schema.ts SCOPE note).
11
+ const reasoningEffort = v.union(v.literal("none"), v.literal("low"), v.literal("medium"), v.literal("high"));
12
+ const modelProvider = v.union(v.literal("gateway"), v.literal("openrouter"));
13
+ const maxInputTokensPerSession = v.union(v.number(), v.literal(false));
11
14
  const agentDoc = v.object({
12
15
  _id: v.id("agents"),
13
16
  _creationTime: v.number(),
14
17
  orgId: v.string(),
15
18
  name: v.string(),
19
+ description: v.optional(v.string()),
16
20
  instructions: v.string(),
17
21
  model: v.string(),
22
+ reasoningEffort: v.optional(reasoningEffort),
23
+ modelProvider: v.optional(modelProvider),
24
+ maxSubagents: v.optional(v.number()),
25
+ maxInputTokensPerSession: v.optional(maxInputTokensPerSession),
18
26
  status: v.union(v.literal("draft"), v.literal("live"), v.literal("archived")),
19
27
  createdBy: v.string(),
20
28
  createdAt: v.number(),
@@ -25,8 +33,13 @@ export const create = mutation({
25
33
  orgId: v.string(),
26
34
  createdBy: v.string(),
27
35
  name: v.string(),
36
+ description: v.optional(v.string()),
28
37
  instructions: v.string(),
29
38
  model: v.string(),
39
+ reasoningEffort: v.optional(reasoningEffort),
40
+ modelProvider: v.optional(modelProvider),
41
+ maxSubagents: v.optional(v.number()),
42
+ maxInputTokensPerSession: v.optional(maxInputTokensPerSession),
30
43
  },
31
44
  returns: v.id("agents"),
32
45
  handler: async (ctx, args) => {
@@ -43,12 +56,20 @@ export const create = mutation({
43
56
  if (args.model.trim().length === 0) {
44
57
  throw new Error("Validation: model must not be empty");
45
58
  }
59
+ if (args.maxSubagents !== undefined && args.maxSubagents < 0) {
60
+ throw new Error("Validation: maxSubagents must not be negative");
61
+ }
46
62
  const now = Date.now();
47
63
  return await ctx.db.insert("agents", {
48
64
  orgId,
49
65
  name: args.name,
66
+ description: args.description,
50
67
  instructions: args.instructions,
51
68
  model: args.model,
69
+ reasoningEffort: args.reasoningEffort,
70
+ modelProvider: args.modelProvider,
71
+ maxSubagents: args.maxSubagents,
72
+ maxInputTokensPerSession: args.maxInputTokensPerSession,
52
73
  status: "live",
53
74
  createdBy: args.createdBy,
54
75
  createdAt: now,
@@ -0,0 +1,13 @@
1
+ export declare const schedule: import("convex/server").RegisteredMutation<"public", {
2
+ orgId: string;
3
+ sessionId: import("convex/values").GenericId<"sessions">;
4
+ awaitedEventName: string;
5
+ timeoutMs: number;
6
+ }, Promise<import("convex/values").GenericId<"awaitEventTimeouts">>>;
7
+ export declare const cancel: import("convex/server").RegisteredMutation<"public", {
8
+ orgId: string;
9
+ timeoutRowId: import("convex/values").GenericId<"awaitEventTimeouts">;
10
+ }, Promise<null>>;
11
+ export declare const fire: import("convex/server").RegisteredMutation<"internal", {
12
+ timeoutRowId: import("convex/values").GenericId<"awaitEventTimeouts">;
13
+ }, Promise<null>>;
@@ -0,0 +1,81 @@
1
+ import { v } from "convex/values";
2
+ import { internal } from "../_generated/api.js";
3
+ import { internalMutation, mutation } from "../_generated/server.js";
4
+ import { assertSameOrg, requireOrgId } from "../lib/auth.js";
5
+ // engine/awaitEventTimeout — self-built timeout for step.awaitEvent
6
+ // (workflow#177: "Convex does not provide a native timeout for
7
+ // awaitEvent"). We schedule a mutation that
8
+ // fires a "blank" `sandbox.timeout` sessionEvent at the deadline; the
9
+ // workflow's `awaitEvent` call is written to also accept this event name so
10
+ // it wakes up even if the awaited event never arrives. Pattern:
11
+ // maintainer's posted code in workflow#177, adapted to our sessionEvents
12
+ // table.
13
+ //
14
+ // NOTE ("intentional divergence from Eve"): orgId is an EXPLICIT ARGUMENT on
15
+ // every public function, never derived from `ctx.auth` -- auth does NOT
16
+ // propagate across a component boundary (component/lib/auth.ts). Also:
17
+ // `sessionEvents.name`'s union in component/schema.ts did not previously
18
+ // include `sandbox.timeout` -- it has been added there (and mirrored in
19
+ // `engine/sessions.listEvents`'s return validator) as part of this
20
+ // migration, otherwise `fire`'s insert below would not compile under the
21
+ // strict build.
22
+ export const schedule = mutation({
23
+ args: {
24
+ orgId: v.string(),
25
+ sessionId: v.id("sessions"),
26
+ awaitedEventName: v.string(),
27
+ timeoutMs: v.number(),
28
+ },
29
+ returns: v.id("awaitEventTimeouts"),
30
+ handler: async (ctx, args) => {
31
+ const orgId = requireOrgId(args.orgId);
32
+ const session = await ctx.db.get(args.sessionId);
33
+ assertSameOrg(orgId, session, "Session not found");
34
+ if (args.timeoutMs <= 0) {
35
+ throw new Error("Validation: timeoutMs must be > 0");
36
+ }
37
+ const timeoutRowId = await ctx.db.insert("awaitEventTimeouts", {
38
+ orgId,
39
+ sessionId: args.sessionId,
40
+ awaitedEventName: args.awaitedEventName,
41
+ deadlineAt: Date.now() + args.timeoutMs,
42
+ });
43
+ const scheduledFunctionId = await ctx.scheduler.runAfter(args.timeoutMs, internal.engine.awaitEventTimeout.fire, { timeoutRowId });
44
+ await ctx.db.patch(timeoutRowId, { scheduledFunctionId });
45
+ return timeoutRowId;
46
+ },
47
+ });
48
+ export const cancel = mutation({
49
+ args: { orgId: v.string(), timeoutRowId: v.id("awaitEventTimeouts") },
50
+ returns: v.null(),
51
+ handler: async (ctx, args) => {
52
+ const orgId = requireOrgId(args.orgId);
53
+ const row = await ctx.db.get(args.timeoutRowId);
54
+ assertSameOrg(orgId, row, "Timeout not found");
55
+ if (!row.firedAt && !row.cancelledAt && row.scheduledFunctionId) {
56
+ await ctx.scheduler.cancel(row.scheduledFunctionId);
57
+ await ctx.db.patch(args.timeoutRowId, { cancelledAt: Date.now() });
58
+ }
59
+ return null;
60
+ },
61
+ });
62
+ // internal — invoked only by the scheduler, never by a client.
63
+ export const fire = internalMutation({
64
+ args: { timeoutRowId: v.id("awaitEventTimeouts") },
65
+ returns: v.null(),
66
+ handler: async (ctx, args) => {
67
+ const row = await ctx.db.get(args.timeoutRowId);
68
+ if (!row || row.firedAt || row.cancelledAt) {
69
+ return null; // already resolved by the real event or by a prior fire
70
+ }
71
+ await ctx.db.patch(args.timeoutRowId, { firedAt: Date.now() });
72
+ await ctx.db.insert("sessionEvents", {
73
+ orgId: row.orgId,
74
+ sessionId: row.sessionId,
75
+ name: "sandbox.timeout",
76
+ payload: JSON.stringify({ awaitedEventName: row.awaitedEventName }),
77
+ createdAt: Date.now(),
78
+ });
79
+ return null;
80
+ },
81
+ });