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

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 (39) hide show
  1. package/README.md +229 -40
  2. package/dist/component/_generated/api.d.ts +31 -0
  3. package/dist/component/_generated/component.d.ts +346 -2
  4. package/dist/component/convex.config.js +19 -0
  5. package/dist/component/engine/agents.d.ts +10 -0
  6. package/dist/component/engine/agents.js +21 -0
  7. package/dist/component/engine/awaitEventTimeout.d.ts +13 -0
  8. package/dist/component/engine/awaitEventTimeout.js +82 -0
  9. package/dist/component/engine/delegation.d.ts +75 -0
  10. package/dist/component/engine/delegation.js +329 -0
  11. package/dist/component/engine/directory.d.ts +9 -0
  12. package/dist/component/engine/directory.js +45 -0
  13. package/dist/component/engine/habits.d.ts +70 -0
  14. package/dist/component/engine/habits.js +219 -0
  15. package/dist/component/engine/mandates.d.ts +74 -0
  16. package/dist/component/engine/mandates.js +272 -0
  17. package/dist/component/engine/sandboxCallback.d.ts +36 -0
  18. package/dist/component/engine/sandboxCallback.js +262 -0
  19. package/dist/component/engine/sessions.d.ts +6 -2
  20. package/dist/component/engine/sessions.js +42 -5
  21. package/dist/component/engine/vpConnection.d.ts +69 -0
  22. package/dist/component/engine/vpConnection.js +221 -0
  23. package/dist/component/engine/wakeup.d.ts +33 -0
  24. package/dist/component/engine/wakeup.js +230 -0
  25. package/dist/component/engine/workflows.d.ts +11 -0
  26. package/dist/component/engine/workflows.js +87 -0
  27. package/dist/component/schema.d.ts +365 -4
  28. package/dist/component/schema.js +353 -1
  29. package/dist/component/testFixtures/delegationDemoWorkflow.d.ts +18 -0
  30. package/dist/component/testFixtures/delegationDemoWorkflow.js +76 -0
  31. package/dist/component/testFixtures/sandboxDemoWorkflow.d.ts +19 -0
  32. package/dist/component/testFixtures/sandboxDemoWorkflow.js +69 -0
  33. package/dist/component/testFixtures/vpTool.d.ts +4 -0
  34. package/dist/component/testFixtures/vpTool.js +25 -0
  35. package/dist/component/testFixtures/wakeupDemoWorkflow.d.ts +19 -0
  36. package/dist/component/testFixtures/wakeupDemoWorkflow.js +77 -0
  37. package/dist/component/testFixtures/wakeupWork.d.ts +8 -0
  38. package/dist/component/testFixtures/wakeupWork.js +21 -0
  39. package/package.json +2 -1
package/README.md CHANGED
@@ -37,12 +37,17 @@ ligne"** below, in this table and in the code comments next to the field.
37
37
  | `dynamicTools` / tools | `manifest.ts:722-725` | resolved at read-time from `connections` + `toolApprovals` | direct parity |
38
38
  | Tool `approval: Approval<...>` (`always`/`once`/`never`) | `public/definitions/tool.ts:117-125` | `toolApprovals` child table | direct parity |
39
39
  | MCP/OpenAPI connections (`defineMcpClientConnection`) | `public/definitions/connections/mcp.ts:23-48` | `connections` child table | direct parity. Our VantagePeers tools (memory, tasks, messages, notes) are wired here as an MCP connection, on by default — **notre ligne**, mvp §2.2 |
40
- | Declared subagents, root-only `agent` tool | https://eve.dev/docs/subagents | `subagents` child table (`parentAgentId` -> `childAgentId`, recursive) | direct parity. **Isolation strict, "inherits nothing from the root's authored slots"** — a subagent row only declares the link + exposed tool name; it never inlines the parent's skills/connections/approvals |
40
+ | Declared subagents (named tool, strict isolation) | https://eve.dev/docs/subagents ("a declared subagent inherits nothing from the root's authored slots") | `subagents` child table (`parentAgentId` -> `childAgentId`, recursive) + `engine/delegation.declareSubagent` / `listSubagents` (I6) | direct parity. Isolation is by construction: `declareSubagent` writes ONLY the link + `toolName`; the child's own slots are only ever read through `engine/resolvers.resolveManifest` against a session on `childAgentId` — never copied onto the parent (proven: `engineDelegation.test.ts`, "manifest carries ONLY its own skills") |
41
+ | Subagent tool-name collision -> **build rejected** | https://eve.dev/docs/subagents ("eve rejects the build rather than picking a winner") | `engine/delegation.declareSubagent`'s build-time collision guard (`by_org_parent_tool` index + reserved `"agent"` name + `toolApprovals` lookup) | direct parity — a colliding `declareSubagent` call throws and writes nothing, never picks a silent winner |
42
+ | Built-in `agent` tool — clone of the root, root-only, **NOT recursive** | https://eve.dev/docs/subagents | `engine/delegation.invokeAgentClone`, `agentCloneRuns` child table, `viaAgentTool` recursion guard | direct parity — a clone invocation cannot invoke the `agent` tool again; refused before any row is written or the wake-up pool is touched |
43
+ | Inter-agent delegation mechanism | not modeled explicitly in `vercel/eve`'s own docs | `engine/delegation.delegateToSubagent` / `invokeAgentClone`, BOTH terminate in the SAME public `engine.wakeup.enqueue` (T4/I2) — one pause/wake system, not two (SYNTHESE §4.d) | **notre ligne (mechanism)** — delegation IS a wake-up: A parks on `step.awaitEvent`, B's work is enqueued through `wakeupPool`, `onComplete` -> `sendEvent` wakes A. No second `onComplete`/`sendEvent` path exists anywhere in this engine |
41
44
  | `sandbox` | `agent-definition.ts:150-160` | `sandboxConfig` child table (Vercel Sandbox, egress policy, allowlist) | direct parity, I0 §8 |
42
45
  | `schedules` / hooks -> "habits" | `manifest.ts:143`, `:726` | `habits` + `habitRuns` child tables (dynamic cron per agent/org, `@convex-dev/crons`, see "Mandates & habits (T4)" below) | **notre ligne (naming + mechanism)** — Eve calls these schedules/hooks; we call them habits (product decision) and back them with runtime-registered crons instead of static config |
43
46
  | *(no equivalent)* — bounded per-agent authority | not present in `vercel/eve` | `mandates` + `approvalRequests` child tables (`@convex-dev/rate-limiter` + `@convex-dev/sharded-counter`, see "Mandates & habits (T4)" below) | **notre ligne** — SYNTHESE §2 "la réponse à la peur de lâcher les commandes"; a weighted, data-driven spending cap per org+agent+scope, overrun => human approval request, never a silent workaround |
44
47
  | Session/turn resolver boundaries (`ALLOWED_DYNAMIC_INSTRUCTION_EVENTS = {session.started, turn.started}`) | `dynamic-tool-definition.ts:40-46` | `sessionEvents.name` union (`session.started`, `turn.started`, ...) + `engine/resolvers.ts:resolveManifest` | direct parity — same event names, same "reread the aggregate, never cache" contract |
45
- | `subagents` used for inter-agent collaboration | eve docs | **not used** — collaboration goes through VantagePeers MCP tools instead | **notre ligne** — explicit Laurent decision (mvp-evevantage.md §2.5): "la collaboration entre agents n'arrive pas par les `subagents` d'eve" |
48
+ | VantagePeers tools (memory, tasks, messages, notes) as a connection | not in `vercel/eve` (no equivalent first-party integration) | `vpConnections` child table (4 booleans, ON by default) + `engine/vpConnection.invokeVpTool` (I6, mvp §2.2 "Travail d'équipe") | **notre ligne** — direct access, NOT network: dispatch is a caller-supplied Convex function handle (`createFunctionHandle`, same discipline as `wakeableWork.workId` / `durableJobs.stepFunctionHandle`), never a `fetch()` call. `orgId` is threaded explicitly into the target handle so a VP write always lands in the invoking agent's own org tenant (`engineDelegation.test.ts` proves both the write and the cross-org refusal) |
49
+ | Agent directory, scoped by org | not in `vercel/eve` | `directory.listByOrg` (I6) | **notre ligne** — same `by_org` index discipline as every other list in this engine; reports each agent's subagent/connection counts alongside `agents.list` |
50
+ | ~~`subagents` NOT used for inter-agent collaboration~~ | eve docs / mvp-evevantage.md §2.5 (T4-era decision) | superseded by I6 — see the delegation rows above | **REVISED, T6/I6**: the T4-era README claimed "la collaboration entre agents n'arrive pas par les `subagents` d'eve" (VantagePeers-only). I6 wires `subagents` up for real, by the SAME pause/wake mechanism as everything else in this engine (SYNTHESE §4.d) — VantagePeers connection tools (row above) remain available IN ADDITION, not as a replacement |
46
51
  | `outputSchema`, `compaction`, `modelOptions`, `channels` | `agent-definition.ts:124-146,313-330`, `manifest.ts:56-77` | out of scope this lot | left for a later I-cycle, documented as deliberately deferred (mvp §2.5) |
47
52
 
48
53
  ## Data aggregate — schema (`convex/schema.ts`)
@@ -59,8 +64,10 @@ Child tables (>= 7, every index starts with `orgId`):
59
64
  6. `toolApprovals` — `always` / `once` / `never` per tool
60
65
  7. `modelKeys` — BYOK, server-only, split from `agents`
61
66
  8. `mandates` (+ `approvalRequests`) — bounded authority (notre ligne, T4)
67
+ 9. `vpConnections` (+ `vpToolInvocations`) — VantagePeers connection toggles + audit trail (notre ligne, T6/I6)
62
68
 
63
- Engine tables: `sessions`, `sessionEvents`, `awaitEventTimeouts`.
69
+ Engine tables: `sessions`, `sessionEvents`, `awaitEventTimeouts`,
70
+ `delegationRuns`, `agentCloneRuns` (I6 — see "Delegation (T6/I6)" below).
64
71
 
65
72
  **Hard rule**: `orgId` is derived server-side from the authenticated
66
73
  identity (`convex/lib/auth.ts:requireOrgId`, reads the Clerk `org_id`
@@ -194,6 +201,64 @@ recurrence is a **dynamically registered `@convex-dev/crons` job**
194
201
  its first run without a deploy" and "a disabled habit does not fire
195
202
  again" PROVABLE in `habits.test.ts` rather than asserted on trust.
196
203
 
204
+ ## Delegation (T6/I6) — `engine/delegation.ts`, `engine/vpConnection.ts`, `directory.ts`
205
+
206
+ Bible: SYNTHESE §4.d — "un agent qui délègue à un autre agent = LE MÊME
207
+ système pause/réveil (awaitEvent/sendEvent) que le pont sandbox — un seul
208
+ système à écrire, pas deux".
209
+
210
+ ### (a) Two delegation semantics, both reusing `engine.wakeup.enqueue`
211
+
212
+ - **Declared subagents** (`subagents` table, `engine/delegation.ts`):
213
+ strict isolation — `declareSubagent` writes ONLY the parent->child link +
214
+ the named tool (`toolName`); the child's own aggregate is the sole place
215
+ its skills/connections/toolApprovals ever live (read via
216
+ `engine/resolvers.resolveManifest` against a session on `childAgentId`).
217
+ **Build-time collision guard**: `toolName` must be unique against (1) the
218
+ reserved built-in `"agent"` tool name, (2) every other declared subagent
219
+ of the same parent (`by_org_parent_tool` index), (3) an existing
220
+ `toolApprovals` row on the parent — any collision REJECTS the mutation,
221
+ never a silent "last one wins" (eve.dev/docs/subagents, verbatim).
222
+ - **Built-in `agent` tool** (`invokeAgentClone`, `agentCloneRuns` table):
223
+ a clone of the ROOT, root-only, NOT recursive. `viaAgentTool: true`
224
+ (a recursive attempt) is refused BEFORE any row is written or
225
+ `engine.wakeup.enqueue` is ever called.
226
+ - **The reuse point**: `delegateToSubagent` and `invokeAgentClone` BOTH
227
+ terminate in exactly one call to the SAME public `engine.wakeup.enqueue`
228
+ action T4/I2 already ships (`ctx.runAction(api.engine.wakeup.enqueue,
229
+ ...)`) — no bespoke `onComplete`/`sendEvent` path exists in
230
+ `engine/delegation.ts`. `engine/delegationDemoWorkflow.ts` is the
231
+ reference parent-side recipient (same shape as
232
+ `engine/wakeupDemoWorkflow.ts`): it parks on `step.awaitEvent` and
233
+ resumes only when the delegate's work completes.
234
+
235
+ ### (b) VantagePeers connection — `engine/vpConnection.ts`
236
+
237
+ Four toggles (`memoryEnabled`, `tasksEnabled`, `messagesEnabled`,
238
+ `notesEnabled`), ON by default (mvp §2.2 "Travail d'équipe", "quatre
239
+ interrupteurs cochés par défaut" — a missing `vpConnections` row means "use
240
+ the defaults"). `invokeVpTool` dispatches via a caller-supplied Convex
241
+ function handle (`createFunctionHandle`, same discipline as
242
+ `wakeableWork.workId` / `durableJobs.stepFunctionHandle`) — **direct
243
+ access, zero network in the hot path**:
244
+
245
+ ```
246
+ $ grep -n "fetch(" convex/engine/vpConnection.ts convex/engine/delegation.ts
247
+ (no matches)
248
+ ```
249
+
250
+ `orgId` is threaded explicitly into the target handle's args (never a
251
+ client-supplied value, never the target's own `ctx.auth`), so a VP tool
252
+ call always writes into the CALLING agent's own org tenant — proven in
253
+ `engineDelegation.test.ts` alongside the cross-org refusal (an agent
254
+ belonging to another org is "not found", same deny-by-default posture as
255
+ everywhere else in this engine).
256
+
257
+ ### (c) Agent directory — `directory.ts`
258
+
259
+ `directory.listByOrg` — every agent of the caller's own org (server-derived
260
+ `orgId`, `by_org` index), plus each agent's subagent/connection counts.
261
+
197
262
  ## `convex/_generated/` freshness -- two gates, not one
198
263
 
199
264
  `convex/_generated/api.d.ts` carries an "AUTOMATICALLY GENERATED" header
@@ -320,6 +385,28 @@ that all contributors run) is Pi's to make, not this PR's.
320
385
  against `component/_generated/api` — the exact source tree compiled to
321
386
  `dist/component/` and published — proving the migrated, packaged code
322
387
  itself, not only the repo-root dev app.
388
+ - `convex/engineWakeup.test.ts` — I2 wake-up primitive (`enqueue` ->
389
+ `onComplete` -> `sendEvent`), three-pole probe + org isolation.
390
+ - `convex/engineSandboxCallback.test.ts` — I5 sandbox bridge (signed
391
+ callback, dedup, timeout, dead-letter).
392
+ - `convex/engineDelegation.test.ts` — I6 delegation, three-pole probe:
393
+ MUST_PASS (a declared subagent's manifest carries only its own skills;
394
+ `declareSubagent` succeeds on a fresh name; `invokeAgentClone` succeeds
395
+ for a first-level call; VP toggles default ON; `invokeVpTool` writes
396
+ into the calling org's tenant; `directory.listByOrg` scoped to the
397
+ caller's org), MUST_BLOCK (a subagent tool-name collision with an
398
+ existing tool OR the reserved `"agent"` name is rejected and writes
399
+ nothing; a recursive `invokeAgentClone` call is refused before any row
400
+ is written; a cross-org `invokeVpTool` call is refused; a disabled VP
401
+ tool is refused; zero `fetch(` calls in the VP connection hot path),
402
+ MUST_REFUSE (every mutation/action above with no identity names
403
+ "Unauthenticated" rather than crashing unreadably).
404
+ - `convex/engineDelegationDemo.test.ts` — the real pause/wake delegation
405
+ demo (A delegates to B via `engine.delegation.delegateToSubagent`, B's
406
+ work completes through `wakeupPool`, A's parked workflow resumes),
407
+ console-logged verbatim (`[i6-demo]` prefix) and kept in its own file
408
+ because it drives `vi.useFakeTimers()` through more event-loop pumps
409
+ than the rest of the suite.
323
410
 
324
411
  Run: `npx vitest run` (or `npm test`).
325
412
 
@@ -372,24 +459,56 @@ orgId-first-index, no-cross-org-reads are unchanged.
372
459
 
373
460
  `component/` (sibling of `convex/`, NOT nested under it — see "Why
374
461
  `component/` and not `convex/component/`" below) hosts the **actual,
375
- compiled, published functions** for a real slice of the engine, not just
376
- the component's identity:
462
+ compiled, published functions** for the FULL agent aggregate as of
463
+ 0.1.0-alpha.6 (C1-C6, all merged) — not just the component's identity:
377
464
 
378
465
  - `component/schema.ts` — `durableJobs`, `agents`, `toolApprovals`,
379
- `sessions`, `sessionEvents` (+ a test-only `callerStepInvocations`
380
- fixture table).
466
+ `sessions`, `sessionEvents`, `wakeableWork`, `awaitEventTimeouts`,
467
+ `mandates`, `approvalRequests`, `habits`, `habitRuns`, `sandboxConfig`,
468
+ `sandboxRuns`, `sandboxCallbackDeliveries`, `sandboxCallbackDeadLetters`,
469
+ `subagents`, `delegationRuns`, `agentCloneRuns`, `vpConnections`,
470
+ `vpToolInvocations` (+ test-only fixture tables: `callerStepInvocations`,
471
+ `wakeupDemoResults`, `vpTenantFixture`).
381
472
  - `component/engine/durableJob.ts` — `start` / `getStatus` / `cancel`
382
473
  (public contract) + `durableJobWorkflowV1` (the versioned pause/resume/
383
474
  replay workflow) + its internal step-runner mutations.
384
- - `component/engine/agents.ts` — `create` / `get` (minimal root-sheet
385
- bootstrap; no `update`/`list`/skills/connections in this pass).
475
+ - `component/engine/agents.ts` — `create` / `get` (root-sheet bootstrap,
476
+ now including `description`/`reasoningEffort`/`modelProvider`/
477
+ `maxSubagents`/`maxInputTokensPerSession`; `update`/skills/connections
478
+ CRUD remain out of scope for this pass).
479
+ - `component/engine/directory.ts` — `listByOrg` (agent directory listing).
386
480
  - `component/engine/resolvers.ts` — `resolveManifest` (dynamic reread at
387
481
  session/turn boundaries; returns `agentId`/`name`/`instructions`/`model`/
388
482
  `toolApprovals` — `skills`/`connections` NOT included in this pass).
389
483
  - `component/engine/sessions.ts` — the conversation thread contract:
390
484
  `start` / `sendTurn` / `appendReasoning` / `requestToolCall` /
391
- `completeToolCall` / `completeTurn` / `listEvents`.
485
+ `completeToolCall` / `completeTurn` / `listEvents`, now piloted by a
486
+ versioned `@convex-dev/workflow` run (`sessionWorkflowV1`,
487
+ `component/engine/workflows.ts` — C1.5).
488
+ `sessions.start` returns `{ sessionId, workflowId }`.
392
489
  - `component/engine/toolApprovals.ts` — `respond`.
490
+ - `component/engine/wakeup.ts` — `enqueue` / `cancel` / `getStatus` +
491
+ `onWorkComplete` (the wake-without-polling primitive; funds through
492
+ `mandates.spendInternal` before any work enters the pool — C2/C3 seam).
493
+ - `component/engine/awaitEventTimeout.ts` — self-built `step.awaitEvent`
494
+ timeout (workflow#177: Convex has no native timeout for it).
495
+ - `component/engine/mandates.ts` — `set` / `get` / `spend` /
496
+ `listApprovals` / `resolveApproval` / `usageCount` (autorité bornée,
497
+ fails-closed spend gate; "notre ligne").
498
+ - `component/engine/habits.ts` — `create` / `get` / `listForAgent` /
499
+ `updateSchedule` / `disable` / `enable` / `listRuns` (per-agent dynamic
500
+ cron, zero-redeploy lifecycle via `@convex-dev/crons`; "notre ligne").
501
+ - `component/engine/sandboxCallback.ts` — `startRun` / `attachSandboxId` /
502
+ `getStatus` / `deadLetterMalformed` / `processCallback` (the DB-side
503
+ half of the Vercel Sandbox bridge: dedup + wake + timeout, reusing C2's
504
+ `wakeup` mechanism).
505
+ - `component/engine/delegation.ts` — `declareSubagent` / `listSubagents` /
506
+ `delegateToSubagent` / `invokeAgentClone` (inter-agent delegation and the
507
+ built-in `agent` clone tool, both reusing `wakeup.enqueue` — the SAME
508
+ pause/wake mechanism as the sandbox bridge, one system not two).
509
+ - `component/engine/vpConnection.ts` — `get` / `getToggles` / `setToggles`
510
+ / `invokeVpTool` (the four VantagePeers tools — memory/tasks/messages/
511
+ notes — wired as a connection of the agent aggregate; "notre ligne").
393
512
  - `component/lib/auth.ts` — `requireOrgId` / `assertSameOrg`: see "Trust
394
513
  model" above.
395
514
 
@@ -402,12 +521,14 @@ components.agentEngine.engine.durableJob.start({ orgId, kind, stepFunctionHandle
402
521
  components.agentEngine.engine.durableJob.getStatus({ orgId, jobId }) -> { status, cursor, totalSteps, lastError?, abandonedAtStep? }
403
522
  components.agentEngine.engine.durableJob.cancel({ orgId, jobId }) -> null
404
523
 
405
- components.agentEngine.engine.agents.create({ orgId, createdBy, name, instructions, model }) -> Id<"agents">
524
+ components.agentEngine.engine.agents.create({ orgId, createdBy, name, description?, instructions, model, reasoningEffort?, modelProvider?, maxSubagents?, maxInputTokensPerSession? }) -> Id<"agents">
406
525
  components.agentEngine.engine.agents.get({ orgId, agentId }) -> agent | null
407
526
 
527
+ components.agentEngine.engine.directory.listByOrg({ orgId }) -> { _id, name, status, model, createdAt }[]
528
+
408
529
  components.agentEngine.engine.resolvers.resolveManifest({ orgId, sessionId }) -> { agentId, name, instructions, model, toolApprovals[] }
409
530
 
410
- components.agentEngine.engine.sessions.start({ orgId, agentId, createdBy }) -> Id<"sessions">
531
+ components.agentEngine.engine.sessions.start({ orgId, agentId, createdBy }) -> { sessionId: Id<"sessions">, workflowId: string }
411
532
  components.agentEngine.engine.sessions.sendTurn({ orgId, sessionId, input }) -> null
412
533
  components.agentEngine.engine.sessions.appendReasoning({ orgId, sessionId, chunk }) -> null
413
534
  components.agentEngine.engine.sessions.requestToolCall({ orgId, sessionId, toolName, argsJson }) -> { authorized, approvalPending, denied }
@@ -416,8 +537,74 @@ components.agentEngine.engine.sessions.completeTurn({ orgId, sessionId }) -> nul
416
537
  components.agentEngine.engine.sessions.listEvents({ orgId, sessionId }) -> sessionEvent[]
417
538
 
418
539
  components.agentEngine.engine.toolApprovals.respond({ orgId, sessionId, toolName, decision: "approved"|"denied", updatePolicy?: "always"|"once"|"never" }) -> null
540
+
541
+ components.agentEngine.engine.wakeup.enqueue({ orgId, agentId, mandateScope, cost, reason, workFunctionHandle, workflowId, awaitedEventName }) -> Id<"wakeableWork"> (action)
542
+ components.agentEngine.engine.wakeup.cancel({ orgId, wakeableWorkId }) -> null
543
+ components.agentEngine.engine.wakeup.getStatus({ orgId, wakeableWorkId }) -> { status, resultSummary?, ... }
544
+
545
+ components.agentEngine.engine.mandates.set({ orgId, agentId, scope, kind, rate, period, capacity? }) -> Id<"mandates">
546
+ components.agentEngine.engine.mandates.get({ orgId, agentId, scope }) -> mandate | null
547
+ components.agentEngine.engine.mandates.spend({ orgId, agentId, scope, cost, reason }) -> { ok, approvalId? }
548
+ components.agentEngine.engine.mandates.listApprovals({ orgId, agentId }) -> approvalRequest[]
549
+ components.agentEngine.engine.mandates.resolveApproval({ orgId, approvalId, resolvedBy, status: "approved"|"denied" }) -> null
550
+ components.agentEngine.engine.mandates.usageCount({ orgId, agentId, scope }) -> number
551
+
552
+ components.agentEngine.engine.habits.create({ orgId, agentId, name, cronExpression, prompt }) -> Id<"habits">
553
+ components.agentEngine.engine.habits.get({ orgId, habitId }) -> habit | null
554
+ components.agentEngine.engine.habits.listForAgent({ orgId, agentId }) -> habit[]
555
+ components.agentEngine.engine.habits.updateSchedule({ orgId, habitId, cronExpression }) -> null
556
+ components.agentEngine.engine.habits.disable({ orgId, habitId }) -> null
557
+ components.agentEngine.engine.habits.enable({ orgId, habitId }) -> null
558
+ components.agentEngine.engine.habits.listRuns({ orgId, habitId }) -> habitRun[]
559
+
560
+ components.agentEngine.engine.sandboxCallback.startRun({ orgId, workflowId, awaitedEventName, timeoutMs }) -> Id<"sandboxRuns">
561
+ components.agentEngine.engine.sandboxCallback.attachSandboxId({ orgId, sandboxRunId, sandboxId }) -> null
562
+ components.agentEngine.engine.sandboxCallback.getStatus({ orgId, sandboxRunId }) -> { status, resultSummary?, ... }
563
+ components.agentEngine.engine.sandboxCallback.processCallback({ orgId, sandboxRunId, deliveryId, status, resultSummary? }) -> { outcome: "woke"|"duplicate" } (called ONLY after the app-level HTTP route has verified the HMAC signature — see "notre ligne" below)
564
+ components.agentEngine.engine.sandboxCallback.deadLetterMalformed({ orgId?, deliveryId, reason, rawBody }) -> null
565
+
566
+ components.agentEngine.engine.delegation.declareSubagent({ orgId, parentAgentId, childAgentId, toolName, description? }) -> Id<"subagents">
567
+ components.agentEngine.engine.delegation.listSubagents({ orgId, parentAgentId }) -> subagent[]
568
+ components.agentEngine.engine.delegation.delegateToSubagent({ orgId, subagentId, ... }) -> null (action; reuses `wakeup.enqueue` end to end)
569
+ components.agentEngine.engine.delegation.invokeAgentClone({ orgId, agentId, ... }) -> null (action; the built-in `agent` clone tool, root-only, non-recursive by construction)
570
+
571
+ components.agentEngine.engine.vpConnection.get({ orgId, agentId }) -> vpConnection | null
572
+ components.agentEngine.engine.vpConnection.getToggles({ orgId, agentId }) -> { memoryEnabled, tasksEnabled, messagesEnabled, notesEnabled }
573
+ components.agentEngine.engine.vpConnection.setToggles({ orgId, agentId, memoryEnabled?, tasksEnabled?, messagesEnabled?, notesEnabled? }) -> Id<"vpConnections">
574
+ components.agentEngine.engine.vpConnection.invokeVpTool({ orgId, agentId, tool, vpFunctionHandle, argsJson }) -> null (action; direct access via `createFunctionHandle`, never `fetch()`)
419
575
  ```
420
576
 
577
+ **Deliberately app-level, NOT ported into the component boundary** — this
578
+ is a measured platform boundary (C5 recherche-d'abord), not an unfinished
579
+ migration:
580
+
581
+ - The public HTTP route (`/sandbox/callback`) that reads
582
+ `SANDBOX_CALLBACK_SECRET` and verifies the HMAC signature over the raw
583
+ request body. No official `@convex-dev/*` component ships an `http.ts`
584
+ or reads `process.env` directly (measured: zero hits across all 7
585
+ installed `@convex-dev/*` component dist trees) — a component cannot
586
+ own this. It stays in the consumer app's own `convex/http.ts`, which
587
+ calls `sandboxCallback.processCallback` / `deadLetterMalformed` ONLY
588
+ after the signature has already checked out.
589
+ - The `"use node"` action that actually talks to `@vercel/sandbox`
590
+ (`Sandbox.create()` / `sandbox.runCommand()`). The Convex CLI's own
591
+ component bundler hard-crashes on any `"use node"` file found inside a
592
+ child component directory ("use node directive is not supported in
593
+ components"). It stays app-level and calls INTO this component's public
594
+ `sandboxCallback.startRun` / `attachSandboxId` (and `mandates.spend`)
595
+ instead.
596
+
597
+ Everything else that was previously listed as "not yet callable" —
598
+ `skills`/`subagents`/`habits`/`sandboxConfig`/`mandates`/
599
+ `approvalRequests`/`awaitEventTimeouts`/`wakeableWork`/`engine/wakeup.ts`/
600
+ `engine/workflows.ts`/`vpConnections` — is now hosted under `component/`
601
+ and callable as listed above (C1 through C6, this pass). `skills` and
602
+ `connections` (the agent's own tool-definition and third-party-connection
603
+ tables, distinct from the `subagents`/`vpConnections` tables above) remain
604
+ the one genuinely deferred slice: porting them needs their own
605
+ component-level `convex-test` harness first (Day 128: never ship
606
+ unverified), and is left for the next, separately-scoped migration.
607
+
421
608
  ### `toolApprovals.respond` — `decision` vs `updatePolicy` (0.1.0-alpha.5)
422
609
 
423
610
  Two DISTINCT axes were conflated pre-alpha.5 (VP
@@ -451,29 +638,24 @@ there was no literal for "refuse this turn only". Fixed by splitting them:
451
638
  platform reason as `orgId`, no longer read from `ctx.auth.getUserIdentity()`
452
639
  — the consumer passes the acting user's own identifier.
453
640
 
454
- Verified two ways: (1) `component/durableJob.componentPackaging.test.ts` +
455
- `component/sessions.componentPackaging.test.ts` run `convex-test` directly
456
- against `component/_generated/api` (the exact source tree
457
- `tsc -p tsconfig.build.json` compiles into `dist/component/`, which is
458
- what `npm pack` ships), so the compiled artifact has a real green test
459
- suite behind it, not just the repo-root dev app's; (2) a from-scratch
460
- consumer probe (install the published tarball into a bare `npx convex dev`
461
- project, register the component, call `durableJob.start` + `sessions.start`
462
- from the consumer's own function, passing `orgId` explicitly) — see the
463
- completion report for the verbatim transcript.
464
-
465
- **NOT yet callable through the published component** (still only exists in
466
- this repo's OWN dev/test deployment under `convex/schema.ts` +
467
- `convex/agents.ts` + `convex/skills.ts`, used by `npx convex dev` and the
468
- repo-root `convex-test` suite): `skills`, `connections`, `subagents`,
469
- `habits`, `sandboxConfig`, `modelKeys`, `mandates`, `approvalRequests`,
470
- `awaitEventTimeouts`, `wakeableWork`, `engine/wakeup.ts`,
471
- `engine/workflows.ts` (`sessionWorkflowV1` — this pass's `sessions` is
472
- deliberately NOT tied to a `@convex-dev/workflow` run; see
473
- `component/schema.ts`'s `sessions` table comment for why). Porting each of
474
- those under `component/` without a working component-level `convex-test`
475
- harness behind it would ship unverified code — Day 128 forbids that; it is
476
- deliberately left for the next, separately-scoped migration.
641
+ Verified two ways: (1) every `component/*.componentPackaging.test.ts` file
642
+ (one per migrated module: durableJob, sessions, directory, wakeup,
643
+ awaitEventTimeout, mandates, habits, sandboxCallback, delegation,
644
+ vpConnection) runs `convex-test` directly against `component/_generated/api`
645
+ (the exact source tree `tsc -p tsconfig.build.json` compiles into
646
+ `dist/component/`, which is what `npm pack` ships), so the compiled
647
+ artifact has a real green test suite behind it, not just the repo-root dev
648
+ app's; (2) a from-scratch global consumer probe (install the REAL
649
+ `npm pack` tarball into a bare Convex project outside this repo, register
650
+ the component, call one function from EACH migrated capability from the
651
+ consumer's own function, passing `orgId` explicitly) — see the C7
652
+ completion report for the verbatim transcript and, honestly, whichever
653
+ parts of it required deployment provisioning this repo does not have.
654
+
655
+ Only `skills` and `connections` (the agent's own tool-definition and
656
+ third-party-connection tables) remain genuinely NOT ported — see
657
+ "Deliberately app-level" and the closing paragraph above for the full,
658
+ current boundary.
477
659
 
478
660
  ### Why `component/` and not `convex/component/`
479
661
 
@@ -497,8 +679,15 @@ T1 (schema + durable session engine, PR #1) merged @
497
679
  `9f3401ba63e6e663af95e9e4f5da42bc30b3550b`. I1 (long-task survival
498
680
  contract, `engine/durableJob.ts`) — not merged, Eta reviews. T4 (mandates
499
681
  + habits) — **not merged** — Eta reviews, merge on Pi token. T2-TER (npm
500
- packaging + component identity + publication) and T2-QUATER (this pass:
501
- migrated `durableJob` + its schema + `lib/auth.ts` under the actual
502
- component boundary, `component/`, with its own `_generated/` and its own
503
- green `convex-test` suite) — see "Packaging & publication" above; **not
504
- merged**.
682
+ packaging + component identity + publication) through C6 (agents,
683
+ sessions/workflow, directory, wakeup, awaitEventTimeout, mandates, habits,
684
+ sandbox bridge DB-side, delegation, VantagePeers connection — all ported
685
+ under `component/` with their own green `convex-test` suite) — see
686
+ "Packaging & publication" above.
687
+
688
+ **M-COMPLETION C7** (this pass): version bump to `0.1.0-alpha.6`
689
+ republishing the FULL C1-C6 surface + a from-scratch global consumer probe
690
+ against the real `npm pack` tarball proving packaged surface == built
691
+ surface. npm `latest`/`alpha` tags are NOT repointed by this PR — that is
692
+ a post-merge deployment step, Pi token protocol, same as every prior
693
+ publish. See the C7 completion report for the probe transcript.
@@ -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 {};