@vantageos/agent-engine 0.1.0-alpha.8 → 0.3.0-alpha.1

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 (62) hide show
  1. package/README.md +33 -8
  2. package/dist/component/_generated/api.d.ts +14 -3
  3. package/dist/component/_generated/api.js +0 -25
  4. package/dist/component/_generated/component.d.ts +369 -73
  5. package/dist/component/_generated/component.js +0 -9
  6. package/dist/component/_generated/dataModel.js +0 -9
  7. package/dist/component/_generated/server.js +0 -69
  8. package/dist/component/convex.config.js +0 -44
  9. package/dist/component/engine/agents.d.ts +3 -3
  10. package/dist/component/engine/agents.js +0 -7
  11. package/dist/component/engine/awaitEventTimeout.d.ts +1 -1
  12. package/dist/component/engine/awaitEventTimeout.js +16 -26
  13. package/dist/component/engine/connections.d.ts +74 -0
  14. package/dist/component/engine/connections.js +254 -0
  15. package/dist/component/engine/delegation.d.ts +5 -5
  16. package/dist/component/engine/delegation.js +0 -74
  17. package/dist/component/engine/directory.js +0 -18
  18. package/dist/component/engine/durableJob.d.ts +24 -17
  19. package/dist/component/engine/durableJob.js +182 -138
  20. package/dist/component/engine/mandates.d.ts +2 -2
  21. package/dist/component/engine/mandates.js +0 -59
  22. package/dist/component/engine/queue.d.ts +97 -0
  23. package/dist/component/engine/queue.js +201 -0
  24. package/dist/component/engine/resolvers.d.ts +1 -1
  25. package/dist/component/engine/resolvers.js +6 -18
  26. package/dist/component/engine/sandboxCallback.d.ts +2 -2
  27. package/dist/component/engine/sandboxCallback.js +2 -79
  28. package/dist/component/engine/sandboxConfigProvider.d.ts +9 -0
  29. package/dist/component/engine/sandboxConfigProvider.js +32 -0
  30. package/dist/component/engine/sessions.d.ts +28 -10
  31. package/dist/component/engine/sessions.js +130 -170
  32. package/dist/component/engine/streams.d.ts +47 -0
  33. package/dist/component/engine/streams.js +162 -0
  34. package/dist/component/engine/toolApprovals.d.ts +1 -1
  35. package/dist/component/engine/toolApprovals.js +12 -37
  36. package/dist/component/engine/vpConnection.js +0 -40
  37. package/dist/component/engine/wakeup.d.ts +7 -9
  38. package/dist/component/engine/wakeup.js +54 -127
  39. package/dist/component/engine/workflows.d.ts +26 -8
  40. package/dist/component/engine/workflows.js +59 -64
  41. package/dist/component/engine/world.d.ts +250 -0
  42. package/dist/component/engine/world.js +689 -0
  43. package/dist/component/lib/auth.js +0 -26
  44. package/dist/component/lib/connectionSecret.d.ts +5 -0
  45. package/dist/component/lib/connectionSecret.js +32 -0
  46. package/dist/component/schema.d.ts +240 -175
  47. package/dist/component/schema.js +134 -294
  48. package/package.json +21 -6
  49. package/dist/component/engine/habits.d.ts +0 -70
  50. package/dist/component/engine/habits.js +0 -218
  51. package/dist/component/testFixtures/callerSteps.d.ts +0 -20
  52. package/dist/component/testFixtures/callerSteps.js +0 -90
  53. package/dist/component/testFixtures/delegationDemoWorkflow.d.ts +0 -18
  54. package/dist/component/testFixtures/delegationDemoWorkflow.js +0 -75
  55. package/dist/component/testFixtures/sandboxDemoWorkflow.d.ts +0 -19
  56. package/dist/component/testFixtures/sandboxDemoWorkflow.js +0 -69
  57. package/dist/component/testFixtures/vpTool.d.ts +0 -4
  58. package/dist/component/testFixtures/vpTool.js +0 -25
  59. package/dist/component/testFixtures/wakeupDemoWorkflow.d.ts +0 -19
  60. package/dist/component/testFixtures/wakeupDemoWorkflow.js +0 -77
  61. package/dist/component/testFixtures/wakeupWork.d.ts +0 -8
  62. package/dist/component/testFixtures/wakeupWork.js +0 -21
@@ -1,11 +1,29 @@
1
1
  import { WorkflowManager } from "@convex-dev/workflow";
2
- export declare const resolveManifestInternal: import("convex/server").RegisteredQuery<"internal", {
3
- sessionId: import("convex/values").GenericId<"sessions">;
4
- }, Promise<null>>;
5
- export declare const recordTurnStartedInternal: import("convex/server").RegisteredMutation<"internal", {
6
- sessionId: import("convex/values").GenericId<"sessions">;
7
- }, Promise<null>>;
8
2
  export declare const workflow: WorkflowManager;
9
- export declare const sessionWorkflowV1: import("convex/server").RegisteredMutation<"internal", import("@convex-dev/workflow").WorkflowArgs<{
10
- sessionId: import("convex/values").VId<import("convex/values").GenericId<"sessions">, "required">;
3
+ export declare const resolveManifestInternalV2: import("convex/server").RegisteredQuery<"internal", {
4
+ orgId: string;
5
+ runId: string;
6
+ }, Promise<null>>;
7
+ export declare const sessionWorkflowV2: import("convex/server").RegisteredMutation<"internal", import("@convex-dev/workflow").WorkflowArgs<{
8
+ orgId: import("convex/values").VString<string, "required">;
9
+ runId: import("convex/values").VString<string, "required">;
11
10
  }>, import("@convex-dev/workflow").WorkflowId>;
11
+ export declare const onSessionWorkflowCompleteV2: import("convex/server").RegisteredMutation<"internal", {
12
+ workflowId: import("@convex-dev/workflow").WorkflowId;
13
+ result: {
14
+ kind: "success";
15
+ returnValue: any;
16
+ } | {
17
+ kind: "failed";
18
+ error: string;
19
+ } | {
20
+ kind: "canceled";
21
+ };
22
+ context: {
23
+ orgId: string;
24
+ runId: string;
25
+ };
26
+ }, Promise<null>>;
27
+ export declare const stopBoxInternal: import("convex/server").RegisteredAction<"internal", {
28
+ boxId: string;
29
+ }, Promise<null>>;
@@ -1,84 +1,79 @@
1
- import { WorkflowManager } from "@convex-dev/workflow";
1
+ import { WorkflowManager, vResultValidator, vWorkflowId } from "@convex-dev/workflow";
2
2
  import { v } from "convex/values";
3
3
  import { components, internal } from "../_generated/api.js";
4
- import { internalMutation, internalQuery } from "../_generated/server.js";
5
- // The durable, VERSIONED session workflow. This is what makes
6
- // `sessions.start` open a session PILOTED by `@convex-dev/workflow` rather
7
- // than a bare event table.
8
- //
9
- // Trust model at this boundary: the workflow engine runs with NO end-user
10
- // identity and NO client-supplied orgId (component isolation, same
11
- // discipline as component/engine/durableJob.ts and component/lib/auth.ts).
12
- // Every internal step below reads orgId from the `sessions` row itself --
13
- // never from an argument a workflow step could be handed by a caller.
14
- // Internal (server-to-server only) variants of the resolver/session
15
- // mutations, used by the workflow step handlers below. The workflow engine
16
- // runs with no end-user identity, so these read/write scoped strictly by
17
- // the orgId already recorded on the session row -- never trusting a
18
- // client-supplied orgId.
19
- export const resolveManifestInternal = internalQuery({
20
- args: { sessionId: v.id("sessions") },
4
+ import { internalAction, internalMutation, internalQuery } from "../_generated/server.js";
5
+ import { agentIdOfRun, loadRun } from "./world.js";
6
+ export const workflow = new WorkflowManager(components.workflow);
7
+ export const resolveManifestInternalV2 = internalQuery({
8
+ args: { orgId: v.string(), runId: v.string() },
21
9
  returns: v.null(),
22
10
  handler: async (ctx, args) => {
23
- const session = await ctx.db.get(args.sessionId);
24
- if (!session)
25
- throw new Error("Session not found");
26
- const agent = await ctx.db.get(session.agentId);
27
- if (!agent || agent.orgId !== session.orgId) {
11
+ const run = await loadRun(ctx, args.orgId, args.runId, "session", "Session not found");
12
+ const agent = await ctx.db.get(agentIdOfRun(ctx, run));
13
+ if (!agent || agent.orgId !== args.orgId) {
28
14
  throw new Error("Agent not found");
29
15
  }
30
- // Resolution result is consumed by the caller via the public
31
- // engine/resolvers:resolveManifest query; this internal step exists to
32
- // prove (and test) that the reread happens at each boundary.
33
16
  return null;
34
17
  },
35
18
  });
36
- export const recordTurnStartedInternal = internalMutation({
37
- args: { sessionId: v.id("sessions") },
19
+ export const sessionWorkflowV2 = workflow.define({
20
+ args: { orgId: v.string(), runId: v.string() },
38
21
  returns: v.null(),
39
- handler: async (ctx, args) => {
40
- const session = await ctx.db.get(args.sessionId);
41
- if (!session)
42
- throw new Error("Session not found");
43
- await ctx.db.insert("sessionEvents", {
44
- orgId: session.orgId,
45
- sessionId: args.sessionId,
46
- name: "turn.started",
47
- payload: undefined,
48
- createdAt: Date.now(),
22
+ handler: async (step, args) => {
23
+ await step.runQuery(internal.engine.workflows.resolveManifestInternalV2, {
24
+ orgId: args.orgId,
25
+ runId: args.runId,
49
26
  });
50
27
  return null;
51
28
  },
52
29
  });
53
- // Versioned workflow discipline (workflow#35): "if you change much
54
- // of anything in a workflow while there are ongoing workflows, they'll
55
- // fail." We never edit a workflow function in place once sessions
56
- // reference it -- a breaking change ships as `sessionWorkflowV2`, and the
57
- // deploy is preceded by draining v1 sessions (0 rows with
58
- // sessions.workflowVersion == "v1" and status == "running"). Same
59
- // discipline as `engine/durableJob.ts:durableJobWorkflowV1`.
60
- export const workflow = new WorkflowManager(components.workflow);
61
- // sessionWorkflowV1 -- the durable session loop. At `session.started` and
62
- // at every `turn.started` boundary it rereads the agent aggregate (never
63
- // cached, never compiled) via `resolveManifestInternal`. Tool approvals
64
- // pause the workflow via `step.awaitEvent`, guarded by the self-built
65
- // timeout (workflow#177) once that surface is ported into this component.
66
- export const sessionWorkflowV1 = workflow.define({
67
- args: { sessionId: v.id("sessions") },
30
+ export const onSessionWorkflowCompleteV2 = internalMutation({
31
+ args: {
32
+ workflowId: vWorkflowId,
33
+ context: v.object({ orgId: v.string(), runId: v.string() }),
34
+ result: vResultValidator,
35
+ },
68
36
  returns: v.null(),
69
- handler: async (step, args) => {
70
- // session.started boundary: read the aggregate once at start.
71
- await step.runQuery(internal.engine.workflows.resolveManifestInternal, {
72
- sessionId: args.sessionId,
73
- });
74
- // turn.started boundary: re-read on every turn so an agent/skill edit
75
- // made mid-session is visible at the very next turn, with zero deploy.
76
- await step.runMutation(internal.engine.workflows.recordTurnStartedInternal, {
77
- sessionId: args.sessionId,
37
+ handler: async (ctx, args) => {
38
+ const { orgId, runId } = args.context;
39
+ let agentId;
40
+ try {
41
+ const run = await loadRun(ctx, orgId, runId, "session", "Session not found");
42
+ agentId = agentIdOfRun(ctx, run);
43
+ }
44
+ catch {
45
+ return null;
46
+ }
47
+ const sandboxConfigRow = await ctx.db
48
+ .query("sandboxConfig")
49
+ .withIndex("by_org_agent", (q) => q.eq("orgId", orgId).eq("agentId", agentId))
50
+ .unique();
51
+ const boxId = sandboxConfigRow?.boxId;
52
+ if (!boxId)
53
+ return null;
54
+ await ctx.scheduler.runAfter(0, internal.engine.workflows.stopBoxInternal, {
55
+ boxId,
78
56
  });
79
- await step.runQuery(internal.engine.workflows.resolveManifestInternal, {
80
- sessionId: args.sessionId,
57
+ return null;
58
+ },
59
+ });
60
+ export const stopBoxInternal = internalAction({
61
+ args: { boxId: v.string() },
62
+ returns: v.null(),
63
+ handler: async (_ctx, args) => {
64
+ const apiKey = process.env.BOAT_API_KEY;
65
+ if (!apiKey || apiKey.length === 0) {
66
+ throw new Error("stopBoxInternal: BOAT_API_KEY is not set; refusing to skip the box-stop call silently");
67
+ }
68
+ const baseUrl = process.env.BOX_API_BASE_URL ?? "https://ascii.dev/api/box/v1";
69
+ const response = await fetch(`${baseUrl.replace(/\/$/, "")}/boxes/${encodeURIComponent(args.boxId)}/stop`, {
70
+ method: "POST",
71
+ headers: { Authorization: `Bearer ${apiKey}` },
81
72
  });
73
+ if (!response.ok) {
74
+ const text = await response.text();
75
+ throw new Error(`stopBoxInternal: POST /boxes/${args.boxId}/stop failed (${response.status}): ${text}`);
76
+ }
82
77
  return null;
83
78
  },
84
79
  });
@@ -0,0 +1,250 @@
1
+ import { type DatabaseReader, type MutationCtx } from "../_generated/server.js";
2
+ import type { Id } from "../_generated/dataModel.js";
3
+ declare function slotToEventId(seq: number): string;
4
+ export type AppendEventArgs = {
5
+ orgId: string;
6
+ runId: string | null;
7
+ eventType: string;
8
+ stepId?: string;
9
+ hookId?: string;
10
+ correlationId?: string;
11
+ dataJson: string;
12
+ };
13
+ export declare function appendEventCore(ctx: MutationCtx, args: AppendEventArgs): Promise<{
14
+ event: {
15
+ eventId: string;
16
+ seq: number;
17
+ runId: string;
18
+ eventType: string;
19
+ stepId: string | undefined;
20
+ hookId: string | undefined;
21
+ correlationId: string | undefined;
22
+ dataJson: string;
23
+ createdAt: number;
24
+ };
25
+ run: {
26
+ runId: string;
27
+ status: "completed" | "failed" | "cancelled" | "running";
28
+ eventCount: number;
29
+ createdAt: number;
30
+ updatedAt: number;
31
+ };
32
+ step: {
33
+ runId: string;
34
+ stepId: string;
35
+ status: "completed" | "failed" | "running";
36
+ dataJson: string | undefined;
37
+ createdAt: number;
38
+ updatedAt: number;
39
+ } | null;
40
+ hook: {
41
+ runId: string;
42
+ hookId: string;
43
+ token: string;
44
+ status: "pending" | "disposed";
45
+ createdAt: number;
46
+ updatedAt: number;
47
+ } | null;
48
+ }>;
49
+ export declare const appendEvent: import("convex/server").RegisteredMutation<"public", {
50
+ stepId?: string | undefined;
51
+ hookId?: string | undefined;
52
+ correlationId?: string | undefined;
53
+ orgId: string;
54
+ runId: string | null;
55
+ dataJson: string;
56
+ eventType: string;
57
+ }, Promise<{
58
+ event: {
59
+ eventId: string;
60
+ seq: number;
61
+ runId: string;
62
+ eventType: string;
63
+ stepId: string | undefined;
64
+ hookId: string | undefined;
65
+ correlationId: string | undefined;
66
+ dataJson: string;
67
+ createdAt: number;
68
+ };
69
+ run: {
70
+ runId: string;
71
+ status: "completed" | "failed" | "cancelled" | "running";
72
+ eventCount: number;
73
+ createdAt: number;
74
+ updatedAt: number;
75
+ };
76
+ step: {
77
+ runId: string;
78
+ stepId: string;
79
+ status: "completed" | "failed" | "running";
80
+ dataJson: string | undefined;
81
+ createdAt: number;
82
+ updatedAt: number;
83
+ } | null;
84
+ hook: {
85
+ runId: string;
86
+ hookId: string;
87
+ token: string;
88
+ status: "pending" | "disposed";
89
+ createdAt: number;
90
+ updatedAt: number;
91
+ } | null;
92
+ }>>;
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 findRunIdByCorrelation(ctx: {
99
+ db: DatabaseReader;
100
+ }, orgId: string, correlationId: string): Promise<string | null>;
101
+ export declare function openRun(ctx: MutationCtx, args: {
102
+ orgId: string;
103
+ kind: RunKind;
104
+ data: Record<string, unknown>;
105
+ }): Promise<string>;
106
+ export declare const RUN_WORKFLOW_BOUND = "run_workflow_bound";
107
+ export declare function bindWorkflowToRun(ctx: MutationCtx, args: {
108
+ orgId: string;
109
+ runId: string;
110
+ workflowId: string;
111
+ workflowVersion: string;
112
+ }): Promise<void>;
113
+ export declare function workflowOfRun(ctx: {
114
+ db: DatabaseReader;
115
+ }, orgId: string, runId: string): Promise<{
116
+ workflowId: string;
117
+ workflowVersion: string;
118
+ } | null>;
119
+ export type LoadedRun = {
120
+ runId: string;
121
+ status: RunStatus;
122
+ eventCount: number;
123
+ created: Record<string, unknown>;
124
+ };
125
+ export declare function loadRun(ctx: {
126
+ db: DatabaseReader;
127
+ }, orgId: string, runId: string, kind: RunKind, notFoundMessage: string): Promise<LoadedRun>;
128
+ export declare function agentIdOfRun(ctx: {
129
+ db: DatabaseReader;
130
+ }, run: LoadedRun): Id<"agents">;
131
+ export declare function payloadOrUndefined(dataJson: string): string | undefined;
132
+ export { slotToEventId };
133
+ export declare const getRun: import("convex/server").RegisteredQuery<"public", {
134
+ orgId: string;
135
+ runId: string;
136
+ }, Promise<{
137
+ runId: string;
138
+ status: "completed" | "failed" | "cancelled" | "running";
139
+ eventCount: number;
140
+ createdAt: number;
141
+ updatedAt: number;
142
+ } | null>>;
143
+ export declare const listRuns: import("convex/server").RegisteredQuery<"public", {
144
+ orgId: string;
145
+ }, Promise<{
146
+ runId: string;
147
+ status: "completed" | "failed" | "cancelled" | "running";
148
+ eventCount: number;
149
+ createdAt: number;
150
+ updatedAt: number;
151
+ }[]>>;
152
+ export declare const getStep: import("convex/server").RegisteredQuery<"public", {
153
+ orgId: string;
154
+ runId: string;
155
+ stepId: string;
156
+ }, Promise<{
157
+ runId: string;
158
+ stepId: string;
159
+ status: "completed" | "failed" | "running";
160
+ dataJson: string | undefined;
161
+ createdAt: number;
162
+ updatedAt: number;
163
+ } | null>>;
164
+ export declare const listSteps: import("convex/server").RegisteredQuery<"public", {
165
+ orgId: string;
166
+ runId: string;
167
+ }, Promise<{
168
+ runId: string;
169
+ stepId: string;
170
+ status: "completed" | "failed" | "running";
171
+ dataJson: string | undefined;
172
+ createdAt: number;
173
+ updatedAt: number;
174
+ }[]>>;
175
+ export declare const getEvent: import("convex/server").RegisteredQuery<"public", {
176
+ orgId: string;
177
+ runId: string;
178
+ eventId: string;
179
+ }, Promise<{
180
+ eventId: string;
181
+ seq: number;
182
+ runId: string;
183
+ eventType: string;
184
+ stepId: string | undefined;
185
+ hookId: string | undefined;
186
+ correlationId: string | undefined;
187
+ dataJson: string;
188
+ createdAt: number;
189
+ } | null>>;
190
+ export declare const listEvents: import("convex/server").RegisteredQuery<"public", {
191
+ orgId: string;
192
+ runId: string;
193
+ }, Promise<{
194
+ eventId: string;
195
+ seq: number;
196
+ runId: string;
197
+ eventType: string;
198
+ stepId: string | undefined;
199
+ hookId: string | undefined;
200
+ correlationId: string | undefined;
201
+ dataJson: string;
202
+ createdAt: number;
203
+ }[]>>;
204
+ export declare const listEventsByCorrelationId: import("convex/server").RegisteredQuery<"public", {
205
+ orgId: string;
206
+ correlationId: string;
207
+ }, Promise<{
208
+ eventId: string;
209
+ seq: number;
210
+ runId: string;
211
+ eventType: string;
212
+ stepId: string | undefined;
213
+ hookId: string | undefined;
214
+ correlationId: string | undefined;
215
+ dataJson: string;
216
+ createdAt: number;
217
+ }[]>>;
218
+ export declare const getHook: import("convex/server").RegisteredQuery<"public", {
219
+ orgId: string;
220
+ hookId: string;
221
+ }, Promise<{
222
+ runId: string;
223
+ hookId: string;
224
+ token: string;
225
+ status: "pending" | "disposed";
226
+ createdAt: number;
227
+ updatedAt: number;
228
+ } | null>>;
229
+ export declare const getHookByToken: import("convex/server").RegisteredQuery<"public", {
230
+ orgId: string;
231
+ token: string;
232
+ }, Promise<{
233
+ runId: string;
234
+ hookId: string;
235
+ token: string;
236
+ status: "pending" | "disposed";
237
+ createdAt: number;
238
+ updatedAt: number;
239
+ } | null>>;
240
+ export declare const listHooks: import("convex/server").RegisteredQuery<"public", {
241
+ orgId: string;
242
+ runId: string;
243
+ }, Promise<{
244
+ runId: string;
245
+ hookId: string;
246
+ token: string;
247
+ status: "pending" | "disposed";
248
+ createdAt: number;
249
+ updatedAt: number;
250
+ }[]>>;