@vantageos/agent-engine 0.3.0-alpha.0 → 0.4.0-alpha.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 +1 -1
- package/dist/component/_generated/api.d.ts +26 -2
- package/dist/component/_generated/component.d.ts +20 -1
- package/dist/component/_generated/dataModel.d.ts +38 -0
- package/dist/component/_generated/server.d.ts +106 -0
- package/dist/component/engine/agents.d.ts +3 -3
- package/dist/component/engine/awaitEventTimeout.d.ts +6 -5
- package/dist/component/engine/awaitEventTimeout.js +50 -33
- package/dist/component/engine/delegation.d.ts +6 -6
- package/dist/component/engine/durableJob.d.ts +4 -27
- package/dist/component/engine/durableJob.js +14 -217
- package/dist/component/engine/mandates.d.ts +2 -2
- package/dist/component/engine/resolvers.js +1 -1
- package/dist/component/engine/sessions.d.ts +2 -2
- package/dist/component/engine/sessions.js +10 -38
- package/dist/component/engine/streams.d.ts +1 -1
- package/dist/component/engine/wakeup.d.ts +2 -2
- package/dist/component/engine/workflows.d.ts +3 -27
- package/dist/component/engine/workflows.js +2 -66
- package/dist/component/engine/world.d.ts +28 -30
- package/dist/component/engine/world.js +79 -42
- package/dist/component/schema.d.ts +31 -132
- package/dist/component/schema.js +3 -59
- package/package.json +6 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type DatabaseReader, type MutationCtx } from "../_generated/server.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { Id } from "../_generated/dataModel.js";
|
|
3
3
|
declare function slotToEventId(seq: number): string;
|
|
4
4
|
export type AppendEventArgs = {
|
|
5
5
|
orgId: string;
|
|
@@ -24,7 +24,7 @@ export declare function appendEventCore(ctx: MutationCtx, args: AppendEventArgs)
|
|
|
24
24
|
};
|
|
25
25
|
run: {
|
|
26
26
|
runId: string;
|
|
27
|
-
status: "
|
|
27
|
+
status: "completed" | "failed" | "cancelled" | "running";
|
|
28
28
|
eventCount: number;
|
|
29
29
|
createdAt: number;
|
|
30
30
|
updatedAt: number;
|
|
@@ -32,7 +32,7 @@ export declare function appendEventCore(ctx: MutationCtx, args: AppendEventArgs)
|
|
|
32
32
|
step: {
|
|
33
33
|
runId: string;
|
|
34
34
|
stepId: string;
|
|
35
|
-
status: "
|
|
35
|
+
status: "completed" | "failed" | "running";
|
|
36
36
|
dataJson: string | undefined;
|
|
37
37
|
createdAt: number;
|
|
38
38
|
updatedAt: number;
|
|
@@ -68,7 +68,7 @@ export declare const appendEvent: import("convex/server").RegisteredMutation<"pu
|
|
|
68
68
|
};
|
|
69
69
|
run: {
|
|
70
70
|
runId: string;
|
|
71
|
-
status: "
|
|
71
|
+
status: "completed" | "failed" | "cancelled" | "running";
|
|
72
72
|
eventCount: number;
|
|
73
73
|
createdAt: number;
|
|
74
74
|
updatedAt: number;
|
|
@@ -76,7 +76,7 @@ export declare const appendEvent: import("convex/server").RegisteredMutation<"pu
|
|
|
76
76
|
step: {
|
|
77
77
|
runId: string;
|
|
78
78
|
stepId: string;
|
|
79
|
-
status: "
|
|
79
|
+
status: "completed" | "failed" | "running";
|
|
80
80
|
dataJson: string | undefined;
|
|
81
81
|
createdAt: number;
|
|
82
82
|
updatedAt: number;
|
|
@@ -90,40 +90,38 @@ export declare const appendEvent: import("convex/server").RegisteredMutation<"pu
|
|
|
90
90
|
updatedAt: number;
|
|
91
91
|
} | null;
|
|
92
92
|
}>>;
|
|
93
|
-
export declare
|
|
94
|
-
export declare
|
|
95
|
-
export
|
|
93
|
+
export declare const RUN_KIND_PREFIX = "run:";
|
|
94
|
+
export declare const LEGACY_KIND_PREFIX = "legacy:";
|
|
95
|
+
export type RunKind = "session" | "job";
|
|
96
|
+
export type RunStatus = "running" | "completed" | "failed" | "cancelled";
|
|
97
|
+
export declare function legacyCorrelationId(kind: RunKind, legacyId: string): string;
|
|
98
|
+
export declare function openRun(ctx: MutationCtx, args: {
|
|
96
99
|
orgId: string;
|
|
97
|
-
|
|
98
|
-
legacyId: string;
|
|
100
|
+
kind: RunKind;
|
|
99
101
|
data: Record<string, unknown>;
|
|
100
102
|
}): Promise<string>;
|
|
101
|
-
export declare
|
|
103
|
+
export declare const RUN_WORKFLOW_BOUND = "run_workflow_bound";
|
|
104
|
+
export declare function bindWorkflowToRun(ctx: MutationCtx, args: {
|
|
102
105
|
orgId: string;
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
106
|
+
runId: string;
|
|
107
|
+
workflowId: string;
|
|
108
|
+
workflowVersion: string;
|
|
109
|
+
}): Promise<void>;
|
|
110
|
+
export declare function workflowOfRun(ctx: {
|
|
111
|
+
db: DatabaseReader;
|
|
112
|
+
}, orgId: string, runId: string): Promise<{
|
|
113
|
+
workflowId: string;
|
|
114
|
+
workflowVersion: string;
|
|
115
|
+
} | null>;
|
|
111
116
|
export type LoadedRun = {
|
|
112
117
|
runId: string;
|
|
113
118
|
status: RunStatus;
|
|
114
119
|
eventCount: number;
|
|
115
|
-
legacyId: string | null;
|
|
116
120
|
created: Record<string, unknown>;
|
|
117
121
|
};
|
|
118
122
|
export declare function loadRun(ctx: {
|
|
119
123
|
db: DatabaseReader;
|
|
120
124
|
}, orgId: string, runId: string, kind: RunKind, notFoundMessage: string): Promise<LoadedRun>;
|
|
121
|
-
export declare function legacySessionOf(ctx: {
|
|
122
|
-
db: DatabaseReader;
|
|
123
|
-
}, run: LoadedRun, orgId: string): Promise<Doc<"sessions"> | null>;
|
|
124
|
-
export declare function legacyJobOf(ctx: {
|
|
125
|
-
db: DatabaseReader;
|
|
126
|
-
}, run: LoadedRun, orgId: string): Promise<Doc<"durableJobs"> | null>;
|
|
127
125
|
export declare function agentIdOfRun(ctx: {
|
|
128
126
|
db: DatabaseReader;
|
|
129
127
|
}, run: LoadedRun): Id<"agents">;
|
|
@@ -134,7 +132,7 @@ export declare const getRun: import("convex/server").RegisteredQuery<"public", {
|
|
|
134
132
|
runId: string;
|
|
135
133
|
}, Promise<{
|
|
136
134
|
runId: string;
|
|
137
|
-
status: "
|
|
135
|
+
status: "completed" | "failed" | "cancelled" | "running";
|
|
138
136
|
eventCount: number;
|
|
139
137
|
createdAt: number;
|
|
140
138
|
updatedAt: number;
|
|
@@ -143,7 +141,7 @@ export declare const listRuns: import("convex/server").RegisteredQuery<"public",
|
|
|
143
141
|
orgId: string;
|
|
144
142
|
}, Promise<{
|
|
145
143
|
runId: string;
|
|
146
|
-
status: "
|
|
144
|
+
status: "completed" | "failed" | "cancelled" | "running";
|
|
147
145
|
eventCount: number;
|
|
148
146
|
createdAt: number;
|
|
149
147
|
updatedAt: number;
|
|
@@ -155,7 +153,7 @@ export declare const getStep: import("convex/server").RegisteredQuery<"public",
|
|
|
155
153
|
}, Promise<{
|
|
156
154
|
runId: string;
|
|
157
155
|
stepId: string;
|
|
158
|
-
status: "
|
|
156
|
+
status: "completed" | "failed" | "running";
|
|
159
157
|
dataJson: string | undefined;
|
|
160
158
|
createdAt: number;
|
|
161
159
|
updatedAt: number;
|
|
@@ -166,7 +164,7 @@ export declare const listSteps: import("convex/server").RegisteredQuery<"public"
|
|
|
166
164
|
}, Promise<{
|
|
167
165
|
runId: string;
|
|
168
166
|
stepId: string;
|
|
169
|
-
status: "
|
|
167
|
+
status: "completed" | "failed" | "running";
|
|
170
168
|
dataJson: string | undefined;
|
|
171
169
|
createdAt: number;
|
|
172
170
|
updatedAt: number;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { v } from "convex/values";
|
|
2
2
|
import { mutation, query, } from "../_generated/server.js";
|
|
3
|
+
import { internal } from "../_generated/api.js";
|
|
3
4
|
import { assertSameOrg, requireOrgId } from "../lib/auth.js";
|
|
4
5
|
function pad26(n) {
|
|
5
6
|
return String(n).padStart(26, "0");
|
|
@@ -243,15 +244,31 @@ export async function appendEventCore(ctx, args) {
|
|
|
243
244
|
if (!parsed.token) {
|
|
244
245
|
throw new Error("Validation: hook_created payload requires token");
|
|
245
246
|
}
|
|
247
|
+
const hasDeadline = parsed.expiresAt !== undefined;
|
|
248
|
+
if (hasDeadline) {
|
|
249
|
+
if (!Number.isFinite(parsed.expiresAt)) {
|
|
250
|
+
throw new Error("Validation: hook_created expiresAt must be a number");
|
|
251
|
+
}
|
|
252
|
+
if (!parsed.awaitedEventName) {
|
|
253
|
+
throw new Error("Validation: a hook with expiresAt requires awaitedEventName");
|
|
254
|
+
}
|
|
255
|
+
await loadRun(ctx, orgId, runId, "session", "Validation: a hook with a deadline requires a session run");
|
|
256
|
+
}
|
|
246
257
|
const hookDocId = await ctx.db.insert("worldHooks", {
|
|
247
258
|
orgId,
|
|
248
259
|
runId,
|
|
249
260
|
hookId: args.hookId,
|
|
250
261
|
token: parsed.token,
|
|
251
262
|
status: "pending",
|
|
263
|
+
expiresAt: hasDeadline ? parsed.expiresAt : undefined,
|
|
264
|
+
awaitedEventName: hasDeadline ? parsed.awaitedEventName : undefined,
|
|
252
265
|
createdAt: now,
|
|
253
266
|
updatedAt: now,
|
|
254
267
|
});
|
|
268
|
+
if (hasDeadline) {
|
|
269
|
+
const scheduledFunctionId = await ctx.scheduler.runAt(parsed.expiresAt, internal.engine.awaitEventTimeout.expire, { orgId, hookId: args.hookId });
|
|
270
|
+
await ctx.db.patch(hookDocId, { scheduledFunctionId });
|
|
271
|
+
}
|
|
255
272
|
hookDoc = await ctx.db.get(hookDocId);
|
|
256
273
|
break;
|
|
257
274
|
}
|
|
@@ -264,6 +281,9 @@ export async function appendEventCore(ctx, args) {
|
|
|
264
281
|
.withIndex("by_org_hook", (q) => q.eq("orgId", orgId).eq("hookId", args.hookId))
|
|
265
282
|
.unique();
|
|
266
283
|
assertSameOrg(orgId, existing, "Hook not found");
|
|
284
|
+
if (existing.scheduledFunctionId !== undefined) {
|
|
285
|
+
await ctx.scheduler.cancel(existing.scheduledFunctionId);
|
|
286
|
+
}
|
|
267
287
|
await ctx.db.delete(existing._id);
|
|
268
288
|
hookDoc = null;
|
|
269
289
|
break;
|
|
@@ -346,44 +366,81 @@ export const appendEvent = mutation({
|
|
|
346
366
|
hook: v.union(hookResult, v.null()),
|
|
347
367
|
}),
|
|
348
368
|
handler: async (ctx, args) => {
|
|
349
|
-
if (args.correlationId?.startsWith(
|
|
369
|
+
if (args.correlationId?.startsWith(RUN_KIND_PREFIX) ||
|
|
370
|
+
args.correlationId?.startsWith(LEGACY_KIND_PREFIX)) {
|
|
350
371
|
throw new Error("Validation: invalid correlationId");
|
|
351
372
|
}
|
|
373
|
+
if (args.eventType === RUN_WORKFLOW_BOUND) {
|
|
374
|
+
throw new Error("Validation: invalid eventType");
|
|
375
|
+
}
|
|
352
376
|
return appendEventCore(ctx, args);
|
|
353
377
|
},
|
|
354
378
|
});
|
|
355
|
-
export
|
|
356
|
-
|
|
379
|
+
export const RUN_KIND_PREFIX = "run:";
|
|
380
|
+
export const LEGACY_KIND_PREFIX = "legacy:";
|
|
381
|
+
const LEGACY_KIND_NAME = {
|
|
382
|
+
session: "sessions",
|
|
383
|
+
job: "durableJobs",
|
|
384
|
+
};
|
|
385
|
+
function runKindPrefix(kind) {
|
|
386
|
+
return `${RUN_KIND_PREFIX}${kind}:`;
|
|
357
387
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
.query("worldEvents")
|
|
361
|
-
.withIndex("by_org_correlation", (q) => q.eq("orgId", orgId).eq("correlationId", correlationId))
|
|
362
|
-
.collect();
|
|
363
|
-
return events.find((e) => e.eventType === "run_created")?.runId ?? null;
|
|
388
|
+
function legacyKindPrefix(kind) {
|
|
389
|
+
return `${LEGACY_KIND_PREFIX}${LEGACY_KIND_NAME[kind]}:`;
|
|
364
390
|
}
|
|
365
|
-
export
|
|
391
|
+
export function legacyCorrelationId(kind, legacyId) {
|
|
392
|
+
return `${legacyKindPrefix(kind)}${legacyId}`;
|
|
393
|
+
}
|
|
394
|
+
export async function openRun(ctx, args) {
|
|
366
395
|
const result = await appendEventCore(ctx, {
|
|
367
396
|
orgId: args.orgId,
|
|
368
397
|
runId: null,
|
|
369
398
|
eventType: "run_created",
|
|
370
|
-
correlationId:
|
|
399
|
+
correlationId: `${runKindPrefix(args.kind)}${crypto.randomUUID()}`,
|
|
371
400
|
dataJson: JSON.stringify(args.data),
|
|
372
401
|
});
|
|
373
402
|
return result.event.runId;
|
|
374
403
|
}
|
|
375
|
-
export
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
404
|
+
export const RUN_WORKFLOW_BOUND = "run_workflow_bound";
|
|
405
|
+
function workflowCorrelationId(runId) {
|
|
406
|
+
return `workflow:${runId}`;
|
|
407
|
+
}
|
|
408
|
+
export async function bindWorkflowToRun(ctx, args) {
|
|
379
409
|
await appendEventCore(ctx, {
|
|
380
410
|
orgId: args.orgId,
|
|
381
|
-
runId,
|
|
382
|
-
eventType:
|
|
383
|
-
|
|
384
|
-
dataJson:
|
|
411
|
+
runId: args.runId,
|
|
412
|
+
eventType: RUN_WORKFLOW_BOUND,
|
|
413
|
+
correlationId: workflowCorrelationId(args.runId),
|
|
414
|
+
dataJson: JSON.stringify({
|
|
415
|
+
workflowId: args.workflowId,
|
|
416
|
+
workflowVersion: args.workflowVersion,
|
|
417
|
+
}),
|
|
385
418
|
});
|
|
386
|
-
|
|
419
|
+
}
|
|
420
|
+
export async function workflowOfRun(ctx, orgId, runId) {
|
|
421
|
+
const events = await ctx.db
|
|
422
|
+
.query("worldEvents")
|
|
423
|
+
.withIndex("by_org_correlation", (q) => q.eq("orgId", orgId).eq("correlationId", workflowCorrelationId(runId)))
|
|
424
|
+
.collect();
|
|
425
|
+
let latest = null;
|
|
426
|
+
for (const e of events) {
|
|
427
|
+
if (e.eventType !== RUN_WORKFLOW_BOUND || e.runId !== runId)
|
|
428
|
+
continue;
|
|
429
|
+
if (latest === null || e.seq > latest.seq)
|
|
430
|
+
latest = e;
|
|
431
|
+
}
|
|
432
|
+
if (latest === null)
|
|
433
|
+
return null;
|
|
434
|
+
try {
|
|
435
|
+
const data = JSON.parse(latest.dataJson);
|
|
436
|
+
if (typeof data.workflowId !== "string" || typeof data.workflowVersion !== "string") {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
return { workflowId: data.workflowId, workflowVersion: data.workflowVersion };
|
|
440
|
+
}
|
|
441
|
+
catch {
|
|
442
|
+
return null;
|
|
443
|
+
}
|
|
387
444
|
}
|
|
388
445
|
export async function loadRun(ctx, orgId, runId, kind, notFoundMessage) {
|
|
389
446
|
const run = await ctx.db
|
|
@@ -395,11 +452,11 @@ export async function loadRun(ctx, orgId, runId, kind, notFoundMessage) {
|
|
|
395
452
|
.query("worldEvents")
|
|
396
453
|
.withIndex("by_org_run_seq", (q) => q.eq("orgId", orgId).eq("runId", runId).eq("seq", 1))
|
|
397
454
|
.unique();
|
|
398
|
-
const prefix = `legacy:${kind}:`;
|
|
399
455
|
if (!first ||
|
|
400
456
|
first.eventType !== "run_created" ||
|
|
401
457
|
first.correlationId === undefined ||
|
|
402
|
-
!first.correlationId.startsWith(
|
|
458
|
+
!(first.correlationId.startsWith(runKindPrefix(kind)) ||
|
|
459
|
+
first.correlationId.startsWith(legacyKindPrefix(kind)))) {
|
|
403
460
|
throw new Error(notFoundMessage);
|
|
404
461
|
}
|
|
405
462
|
let created = {};
|
|
@@ -412,33 +469,13 @@ export async function loadRun(ctx, orgId, runId, kind, notFoundMessage) {
|
|
|
412
469
|
catch {
|
|
413
470
|
created = {};
|
|
414
471
|
}
|
|
415
|
-
const legacyId = first.correlationId.slice(prefix.length);
|
|
416
472
|
return {
|
|
417
473
|
runId: run.runId,
|
|
418
474
|
status: run.status,
|
|
419
475
|
eventCount: run.eventCount,
|
|
420
|
-
legacyId: legacyId.length > 0 ? legacyId : null,
|
|
421
476
|
created,
|
|
422
477
|
};
|
|
423
478
|
}
|
|
424
|
-
export async function legacySessionOf(ctx, run, orgId) {
|
|
425
|
-
if (run.legacyId === null)
|
|
426
|
-
return null;
|
|
427
|
-
const id = ctx.db.normalizeId("sessions", run.legacyId);
|
|
428
|
-
if (id === null)
|
|
429
|
-
return null;
|
|
430
|
-
const doc = await ctx.db.get(id);
|
|
431
|
-
return doc !== null && doc.orgId === orgId ? doc : null;
|
|
432
|
-
}
|
|
433
|
-
export async function legacyJobOf(ctx, run, orgId) {
|
|
434
|
-
if (run.legacyId === null)
|
|
435
|
-
return null;
|
|
436
|
-
const id = ctx.db.normalizeId("durableJobs", run.legacyId);
|
|
437
|
-
if (id === null)
|
|
438
|
-
return null;
|
|
439
|
-
const doc = await ctx.db.get(id);
|
|
440
|
-
return doc !== null && doc.orgId === orgId ? doc : null;
|
|
441
|
-
}
|
|
442
479
|
export function agentIdOfRun(ctx, run) {
|
|
443
480
|
const raw = run.created.agentId;
|
|
444
481
|
const id = typeof raw === "string" ? ctx.db.normalizeId("agents", raw) : null;
|