@nylorun/runtime 0.27.0-beta → 0.29.0-beta

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 (160) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +1 -1
  3. package/dist/api/a2a/card.d.ts +4 -3
  4. package/dist/api/a2a/card.js +3 -3
  5. package/dist/api/a2a/routes.js +18 -7
  6. package/dist/api/ag-ui/routes.js +4 -7
  7. package/dist/api/components.d.ts +5854 -2718
  8. package/dist/api/components.js +39 -30
  9. package/dist/api/http/app.js +9 -4
  10. package/dist/api/http/body.d.ts +2 -0
  11. package/dist/api/http/body.js +20 -0
  12. package/dist/api/http/define.d.ts +4 -0
  13. package/dist/api/http/define.js +20 -9
  14. package/dist/api/http/routes/agent-manifests.d.ts +10 -0
  15. package/dist/api/http/routes/agent-manifests.js +135 -0
  16. package/dist/api/http/routes/agents.d.ts +11 -0
  17. package/dist/api/http/routes/agents.js +418 -0
  18. package/dist/api/http/routes/artifacts.js +2 -2
  19. package/dist/api/http/routes/coverage.d.ts +4 -4
  20. package/dist/api/http/routes/coverage.js +12 -6
  21. package/dist/api/http/routes/files.js +1 -1
  22. package/dist/api/http/routes/mcp.js +2 -2
  23. package/dist/api/http/routes/me.d.ts +1 -1
  24. package/dist/api/http/routes/me.js +1 -2
  25. package/dist/api/http/routes/memories.d.ts +9 -0
  26. package/dist/api/http/routes/memories.js +152 -0
  27. package/dist/api/http/routes/reads.d.ts +1 -137
  28. package/dist/api/http/routes/reads.js +31 -12
  29. package/dist/api/http/routes/sessions.js +21 -50
  30. package/dist/api/http/routes/tenant.js +13 -10
  31. package/dist/api/http/routes/triggers.d.ts +10 -0
  32. package/dist/api/http/routes/triggers.js +183 -0
  33. package/dist/api/openapi.js +69 -47
  34. package/dist/artifacts/disk.d.ts +10 -10
  35. package/dist/artifacts/disk.js +27 -27
  36. package/dist/artifacts/quota.d.ts +1 -1
  37. package/dist/artifacts/quota.js +2 -2
  38. package/dist/artifacts/service.js +2 -2
  39. package/dist/core/flow-host.d.ts +0 -1
  40. package/dist/gates/egress-credentials.js +1 -1
  41. package/dist/gates/egress.d.ts +5 -5
  42. package/dist/gates/egress.js +6 -6
  43. package/dist/gates/http-tool.js +2 -2
  44. package/dist/gates/meter.js +22 -5
  45. package/dist/gates/policy.d.ts +8 -3
  46. package/dist/gates/policy.js +7 -2
  47. package/dist/gates/tenant-vaults.d.ts +1 -1
  48. package/dist/harness/pod.d.ts +2 -0
  49. package/dist/harness/setup.js +17 -6
  50. package/dist/harness-api/record.js +11 -0
  51. package/dist/harness-api/server.js +4 -0
  52. package/dist/harness-api/start.d.ts +11 -7
  53. package/dist/harness-api/start.js +49 -5
  54. package/dist/harness-api/workspace.js +2 -2
  55. package/dist/host/config-for.d.ts +2 -0
  56. package/dist/host/config-for.js +1 -0
  57. package/dist/host/http.d.ts +2 -2
  58. package/dist/host/http.js +5 -2
  59. package/dist/host/main.js +1 -0
  60. package/dist/keys/keys.d.ts +15 -4
  61. package/dist/keys/keys.js +16 -0
  62. package/dist/keys/webhooks.d.ts +25 -0
  63. package/dist/keys/webhooks.js +62 -0
  64. package/dist/management-openapi.json +313 -133
  65. package/dist/mcp/connect.d.ts +2 -2
  66. package/dist/mcp/connect.js +3 -3
  67. package/dist/mcp/preview.js +7 -7
  68. package/dist/memory/service.d.ts +97 -0
  69. package/dist/memory/service.js +335 -0
  70. package/dist/memory/tool.d.ts +36 -0
  71. package/dist/memory/tool.js +84 -0
  72. package/dist/model/pi-model.js +7 -0
  73. package/dist/openapi.json +13120 -9034
  74. package/dist/reads/types.d.ts +3 -3
  75. package/dist/record/agent.d.ts +27 -0
  76. package/dist/record/agent.js +46 -0
  77. package/dist/record/index.d.ts +1 -1
  78. package/dist/record/index.js +1 -1
  79. package/dist/sandbox/join.js +5 -5
  80. package/dist/sandbox/placement.d.ts +1 -1
  81. package/dist/sandbox/placement.js +3 -3
  82. package/dist/sandbox/pods/lifecycle.d.ts +6 -6
  83. package/dist/sandbox/pods/lifecycle.js +6 -6
  84. package/dist/sandbox/pods/reconcile.js +10 -2
  85. package/dist/sandbox/resolve.d.ts +3 -3
  86. package/dist/sandbox/resolve.js +7 -7
  87. package/dist/sandbox/setup.d.ts +3 -1
  88. package/dist/sandbox/setup.js +14 -4
  89. package/dist/store/postgres/drizzle/0032_agents.sql +54 -0
  90. package/dist/store/postgres/drizzle/0033_agent_versions.sql +7 -0
  91. package/dist/store/postgres/drizzle/0034_protocol_17_session_queue.sql +13 -0
  92. package/dist/store/postgres/drizzle/0035_t4_triggers.sql +41 -0
  93. package/dist/store/postgres/drizzle/0036_t5_memories.sql +30 -0
  94. package/dist/store/postgres/drizzle/0037_model_usage_cost_split.sql +4 -0
  95. package/dist/store/postgres/drizzle/meta/_journal.json +42 -0
  96. package/dist/store/postgres/reads.js +44 -87
  97. package/dist/store/postgres/record-writer.d.ts +4 -4
  98. package/dist/store/postgres/record-writer.js +9 -9
  99. package/dist/store/postgres/schema.d.ts +1408 -123
  100. package/dist/store/postgres/schema.js +194 -38
  101. package/dist/store/postgres/store.js +329 -79
  102. package/dist/store/postgres/tenant.js +1 -2
  103. package/dist/store/types.d.ts +155 -50
  104. package/dist/store/types.js +0 -1
  105. package/dist/tenant/advance.js +20 -8
  106. package/dist/tenant/agent-manifests.d.ts +72 -0
  107. package/dist/tenant/agent-manifests.js +359 -0
  108. package/dist/tenant/agent-versions.d.ts +126 -0
  109. package/dist/tenant/agent-versions.js +389 -0
  110. package/dist/tenant/agents.d.ts +230 -0
  111. package/dist/tenant/{environments.js → agents.js} +464 -320
  112. package/dist/tenant/auth.d.ts +1 -1
  113. package/dist/tenant/auth.js +3 -3
  114. package/dist/tenant/commands.d.ts +63 -2
  115. package/dist/tenant/commands.js +240 -83
  116. package/dist/tenant/context.d.ts +46 -19
  117. package/dist/tenant/context.js +6 -2
  118. package/dist/tenant/effects.js +7 -16
  119. package/dist/tenant/identity-file.d.ts +6 -6
  120. package/dist/tenant/identity-file.js +12 -10
  121. package/dist/tenant/issuers.js +3 -3
  122. package/dist/tenant/limits.d.ts +0 -3
  123. package/dist/tenant/limits.js +0 -3
  124. package/dist/tenant/memories.d.ts +38 -0
  125. package/dist/tenant/memories.js +119 -0
  126. package/dist/tenant/reset.js +2 -2
  127. package/dist/tenant/run-grants.d.ts +6 -0
  128. package/dist/tenant/run-grants.js +4 -0
  129. package/dist/tenant/runtime.d.ts +1 -1
  130. package/dist/tenant/runtime.js +8 -0
  131. package/dist/tenant/sessions.d.ts +28 -45
  132. package/dist/tenant/sessions.js +85 -208
  133. package/dist/tenant/status.js +6 -7
  134. package/dist/tenant/sweep.js +12 -3
  135. package/dist/tenant/transcript.d.ts +16 -16
  136. package/dist/tenant/triggers.d.ts +143 -0
  137. package/dist/tenant/triggers.js +715 -0
  138. package/dist/tenant/turn-timing.d.ts +11 -1
  139. package/dist/tenant/turn-timing.js +3 -1
  140. package/dist/tenant/types.d.ts +5 -0
  141. package/dist/tenant/worker.d.ts +2 -0
  142. package/dist/tenant/worker.js +5 -0
  143. package/dist/traces/map.d.ts +1 -1
  144. package/dist/traces/map.js +7 -1
  145. package/dist/tuning.d.ts +7 -0
  146. package/dist/tuning.js +19 -0
  147. package/dist/vault/service.d.ts +13 -8
  148. package/dist/vault/service.js +61 -17
  149. package/dist/version.d.ts +1 -1
  150. package/dist/version.js +1 -1
  151. package/package.json +13 -12
  152. package/dist/api/http/routes/environment-manifests.d.ts +0 -9
  153. package/dist/api/http/routes/environment-manifests.js +0 -118
  154. package/dist/api/http/routes/environments.d.ts +0 -11
  155. package/dist/api/http/routes/environments.js +0 -332
  156. package/dist/record/environment.d.ts +0 -27
  157. package/dist/record/environment.js +0 -46
  158. package/dist/tenant/environment-manifests.d.ts +0 -57
  159. package/dist/tenant/environment-manifests.js +0 -208
  160. package/dist/tenant/environments.d.ts +0 -172
@@ -63,11 +63,11 @@
63
63
  import type { KeyRole } from "@nylorun/core/compatibility";
64
64
  import type { RecordReader } from "../streams/relay/types.js";
65
65
  import type { SandboxSignal, Wake } from "../execution/types.js";
66
- import type { EventPayload, EventType, EventWriter, LiveEvent, EnvironmentEvent, EnvironmentEventPayload, EnvironmentEventType, EnvironmentKind, EnvironmentManifest, EnvironmentRecipe, PodDesired, PodObserved, SessionEventOf } from "@nylorun/core/contracts";
66
+ import type { EventPayload, EventType, EventWriter, LiveEvent, AgentEvent, AgentEventPayload, AgentEventType, AgentManifestV8, EnvironmentKind, EnvironmentRecipe, PodDesired, PodObserved, SessionEventOf } from "@nylorun/core/contracts";
67
67
  import type { HostEffect } from "@nylorun/harness/run";
68
- import type { ArtifactRow, ArtifactVersionRow, DefinitionFileRow, ModelBudgetRow, ModelUsageRow, ModelUsageWrite, PrincipalRow, ToolCrossingRow, SigningKeyRow, VaultAuditRow, VaultCredentialRow, VaultIdempotencyRow, VaultRow } from "./postgres/schema.js";
68
+ import type { ArtifactRow, ArtifactVersionRow, DefinitionFileRow, ModelBudgetRow, ModelUsageRow, ModelUsageWrite, PrincipalRow, ToolCrossingRow, QueuedMessageRow, AgentTriggerRow, TriggerRunRow, MemoryRow, MemoryVersionRow, SigningKeyRow, VaultAuditRow, VaultCredentialRow, VaultIdempotencyRow, VaultRow } from "./postgres/schema.js";
69
69
  /** Tables holding JSON documents keyed by `id`. */
70
- export type DocTable = "definitions" | "sessions" | "commands" | "effects" | "sandboxes" | "links";
70
+ export type DocTable = "sessions" | "commands" | "effects" | "sandboxes" | "links";
71
71
  export declare const DOC_TABLES: readonly DocTable[];
72
72
  /** Session lifecycle (architecture §10.2). */
73
73
  export type SessionStatus = "idle" | "runnable" | "running" | "waiting" | "paused" | "uncertain" | "completed" | "failed" | "cancelled";
@@ -117,17 +117,15 @@ export interface LinkDoc {
117
117
  effectId: string;
118
118
  turnId: string;
119
119
  }
120
- /** A definition document. Indexed: `manifest.id`. */
121
- export interface DefinitionDoc {
122
- manifest: {
123
- id: string;
124
- };
125
- }
126
120
  /** A sandbox record, keyed by sandbox key. */
127
121
  export interface SandboxDoc {
128
122
  key: string;
129
123
  }
130
- /** An Environment (`environments`, D55): what `PUT /v1/environments/{id}` created. */
124
+ /**
125
+ * An Agent's row (`agents`; an Environment's before protocol 16): what `PUT /v1/agents/{id}`
126
+ * created. The Runtime's own code calls the part it runs on (its kind, recipe, pod, disk and
127
+ * vault) the Agent's environment, keyed by the Agent's id.
128
+ */
131
129
  export interface Environment {
132
130
  id: string;
133
131
  kind: EnvironmentKind;
@@ -138,7 +136,7 @@ export interface Environment {
138
136
  applied: EnvironmentRecipe;
139
137
  version: number;
140
138
  appliedVersion: number;
141
- /** The owner guard: only this owner's sessions may name it. */
139
+ /** The owner guard (`owner` on the API): only this owner's sessions may run on it. */
142
140
  ownerUserId?: string;
143
141
  /** ISO time it was last used (`lifecycle.deleteAfter` counts from it). */
144
142
  lastUsedAt: string;
@@ -153,16 +151,39 @@ export interface Environment {
153
151
  * Q17): the setup runs once the version is written (`written`), and the seed stays until it is done.
154
152
  */
155
153
  diskSeed?: DiskSeed;
156
- /** The environment manifest it was made from and its version (D63); absent for an inline one. */
157
- manifestName?: string;
158
- manifestVersion?: number;
159
- /** The hash of what it runs (`recipe`), recorded at creation (protocol 14). */
160
- manifestHash?: string;
161
- /** The Environment it was forked from and the disk version it started from (Q15). */
154
+ /** The agent manifest it was made from and the version it resolved then, which it runs. */
155
+ manifestName: string;
156
+ manifestVersion: number;
157
+ /** How it names the manifest: `tracking` (`name`) or `pinned` (`name@n`). */
158
+ manifestRef: "tracking" | "pinned";
159
+ /** The hash of that manifest version. */
160
+ manifestHash: string;
161
+ /** `on`, or `off` once paused (track T6). */
162
+ desiredState: "on" | "off";
163
+ /** The Agent it was forked from and the disk version it started from (Q15). */
162
164
  forkedFrom?: {
163
- environment: string;
165
+ agent: string;
164
166
  disk: number | null;
165
167
  };
168
+ /**
169
+ * The manifest version it moves to while it is outdated (track T3, D73): it waits for its
170
+ * required secrets or its pod's next start. Absent when it runs the version it should.
171
+ */
172
+ targetVersion?: number;
173
+ /** A version that failed to start (T3): a tracking Agent does not move to it again on its own. */
174
+ failedVersion?: number;
175
+ /** While a pod starts on a new version (T3): what it ran before, which a failed start reverts to. */
176
+ startCheck?: AgentStartCheck;
177
+ }
178
+ /** What a pod Agent ran before it started on a new version (track T3), and since when it starts. */
179
+ export interface AgentStartCheck {
180
+ from: {
181
+ manifestVersion: number;
182
+ manifestHash: string;
183
+ applied: EnvironmentRecipe;
184
+ imageDigest?: string;
185
+ };
186
+ startedAt: string;
166
187
  }
167
188
  /** A pending seed of an Environment's disk (`disk_seed`). */
168
189
  export interface DiskSeed {
@@ -173,11 +194,11 @@ export interface DiskSeed {
173
194
  /** The version is written; with `setup`, the seed waits for the setup to be done. */
174
195
  written?: true;
175
196
  }
176
- /** One version of an environment manifest (`environment_manifests`, D63). */
177
- export interface EnvironmentManifestRow {
197
+ /** One version of an agent manifest (`agent_manifests`, protocol 16). */
198
+ export interface AgentManifestRow {
178
199
  name: string;
179
200
  version: number;
180
- body: EnvironmentManifest;
201
+ body: AgentManifestV8;
181
202
  hash: string;
182
203
  savedBy: {
183
204
  actor: string;
@@ -260,11 +281,11 @@ export type CommitListener = (commit: Commit) => void;
260
281
  * `bytea` columns, never inside a JSON body), the vault's audit and idempotency records, the
261
282
  * Tenant's signing keys, a model call in the usage ledger and a model budget.
262
283
  */
263
- export type { ArtifactRow, ArtifactVersionRow, DefinitionFileRow, ModelBudgetRow, ModelUsageRow, ModelUsageWrite, ToolCrossingRow, PrincipalRow, SigningKeyRow, VaultAuditRow, VaultCredentialRow, VaultIdempotencyRow, VaultRow, };
284
+ export type { ArtifactRow, ArtifactVersionRow, DefinitionFileRow, ModelBudgetRow, ModelUsageRow, ModelUsageWrite, ToolCrossingRow, QueuedMessageRow, AgentTriggerRow, TriggerRunRow, MemoryRow, MemoryVersionRow, PrincipalRow, SigningKeyRow, VaultAuditRow, VaultCredentialRow, VaultIdempotencyRow, VaultRow, };
264
285
  /** Which rows of the usage ledger a total covers. */
265
286
  export interface ModelUsageQuery {
266
- scope: "tenant" | "agent" | "turn";
267
- /** The agent or turn id; ignored for `tenant`. */
287
+ scope: "tenant" | "manifest" | "turn";
288
+ /** The agent manifest's name or the turn id; ignored for `tenant`. */
268
289
  id?: string;
269
290
  /** Only rows created at or after this ISO time. */
270
291
  since?: string;
@@ -289,9 +310,9 @@ export interface StoreCounts {
289
310
  /** Effects `uncertain`. */
290
311
  uncertainEffects: number;
291
312
  sandboxes: number;
292
- definitions: number;
313
+ agentManifests: number;
293
314
  }
294
- export type ResetScope = "sessions" | "environments" | "all";
315
+ export type ResetScope = "sessions" | "agents" | "all";
295
316
  /** Result of `takeOwnership`. */
296
317
  export type TakeOwnership = {
297
318
  status: "owned";
@@ -541,9 +562,8 @@ export interface Tx {
541
562
  agentId?: string;
542
563
  ownerUserId?: string;
543
564
  }): Promise<StoredSession<T>[]>;
544
- listDefinitions<T extends DefinitionDoc = DefinitionDoc>(): Promise<T[]>;
545
565
  listSandboxes<T extends SandboxDoc = SandboxDoc>(): Promise<T[]>;
546
- /** Environment `id`; with `lock`, its row is locked until the transaction ends. */
566
+ /** Agent `id`'s row; with `lock`, it is locked until the transaction ends. */
547
567
  environment(id: string, options?: {
548
568
  lock?: boolean;
549
569
  }): Promise<Environment | undefined>;
@@ -554,8 +574,8 @@ export interface Tx {
554
574
  createEnvironment(row: Environment, limit: number): Promise<"created" | "exists" | "limit">;
555
575
  /**
556
576
  * Changes an Environment's columns other than its pod's (the caller holds the row's lock):
557
- * labels, recipe and version, the applied recipe and its version, the owner guard (`null`
558
- * clears it), and when it was last used.
577
+ * labels, recipe and version, the applied recipe and its version, the manifest version it runs
578
+ * and how it names it (track T3), the owner guard (`null` clears it), and when it was last used.
559
579
  */
560
580
  updateEnvironment(id: string, patch: {
561
581
  labels?: Record<string, string>;
@@ -563,6 +583,12 @@ export interface Tx {
563
583
  version?: number;
564
584
  applied?: EnvironmentRecipe;
565
585
  appliedVersion?: number;
586
+ manifestVersion?: number;
587
+ manifestHash?: string;
588
+ manifestRef?: "tracking" | "pinned";
589
+ targetVersion?: number | null;
590
+ failedVersion?: number | null;
591
+ startCheck?: AgentStartCheck | null;
566
592
  ownerUserId?: string | null;
567
593
  lastUsedAt?: string;
568
594
  diskOp?: DiskOperation | null;
@@ -576,32 +602,32 @@ export interface Tx {
576
602
  listEnvironments(filter?: {
577
603
  labels?: Record<string, string>;
578
604
  }): Promise<Environment[]>;
579
- /** Sessions that name Environment `environmentId` (`Session.environmentId`), by id. */
605
+ /** Sessions on Agent `environmentId` (`Session.environmentId`), by id. */
580
606
  sessionsOnEnvironment<T extends SessionDoc = SessionDoc>(environmentId: string): Promise<StoredSession<T>[]>;
581
607
  /**
582
- * Appends an event to the Environment's lifecycle stream through the record module. The
583
- * caller holds the Environment row's lock (or created the row in this transaction).
608
+ * Appends an event to the Agent's lifecycle stream through the record module. The caller holds
609
+ * the Agent row's lock (or created the row in this transaction).
584
610
  */
585
- environmentEvent<T extends EnvironmentEventType>(environmentId: string, type: T, payload: EnvironmentEventPayload<T>): Promise<EnvironmentEvent>;
611
+ agentEvent<T extends AgentEventType>(agentId: string, type: T, payload: AgentEventPayload<T>): Promise<AgentEvent>;
586
612
  /**
587
- * The Environment's stream, from `fromSeq` on, at most `limit` events: only `types` when given,
588
- * and only events recorded at or after `since` and before `until` (ISO times) when given.
613
+ * The Agent's stream, from `fromSeq` on, at most `limit` events: only `types` when given, and
614
+ * only events recorded at or after `since` and before `until` (ISO times) when given.
589
615
  */
590
- environmentEvents(environmentId: string, options?: EnvironmentEventsQuery): Promise<EnvironmentEvent[]>;
616
+ agentEvents(agentId: string, options?: AgentEventsQuery): Promise<AgentEvent[]>;
591
617
  /** Holds manifest `name`'s save lock until the transaction ends, so saves of one name are serial. */
592
- lockEnvironmentManifest(name: string): Promise<void>;
618
+ lockAgentManifest(name: string): Promise<void>;
593
619
  /** Version `version` of manifest `name`, or its latest when `version` is omitted. */
594
- environmentManifest(name: string, version?: number): Promise<EnvironmentManifestRow | undefined>;
620
+ agentManifest(name: string, version?: number): Promise<AgentManifestRow | undefined>;
595
621
  /** Writes a new version (the caller holds the name's lock and chose the next number). */
596
- insertEnvironmentManifest(row: EnvironmentManifestRow): Promise<void>;
622
+ insertAgentManifest(row: AgentManifestRow): Promise<void>;
597
623
  /** Each manifest's latest version, by name. */
598
- listEnvironmentManifests(): Promise<EnvironmentManifestRow[]>;
624
+ listAgentManifests(): Promise<AgentManifestRow[]>;
599
625
  /** Every version of manifest `name`, newest first. */
600
- environmentManifestVersions(name: string): Promise<EnvironmentManifestRow[]>;
626
+ agentManifestVersions(name: string): Promise<AgentManifestRow[]>;
601
627
  /** Deletes every version of manifest `name`; how many there were. */
602
- deleteEnvironmentManifest(name: string): Promise<number>;
603
- /** How many Environments were made from each version of manifest `name` (deleting ones too). */
604
- environmentsOfManifest(name: string): Promise<Map<number, number>>;
628
+ deleteAgentManifest(name: string): Promise<number>;
629
+ /** How many Agents were made from each version of manifest `name` (deleting ones too). */
630
+ agentsOfManifest(name: string): Promise<Map<number, number>>;
605
631
  /** `invoking` effects of one session; takeover turns them `uncertain`. */
606
632
  invokingEffects<T extends EffectDoc = EffectDoc>(sessionId: string): Promise<T[]>;
607
633
  effectsForSession<T extends EffectDoc = EffectDoc>(sessionId: string, filter?: SessionEffectFilter): Promise<T[]>;
@@ -609,6 +635,86 @@ export interface Tx {
609
635
  effectsWithStatus<T extends EffectDoc = EffectDoc>(statuses: readonly (EffectStatus | (string & {}))[], filter?: {
610
636
  kinds?: readonly EffectKind[];
611
637
  }): Promise<T[]>;
638
+ /** Adds a message at the end of its session's queue; returns its position in the queue's order. */
639
+ enqueueMessage(row: Omit<QueuedMessageRow, "seq">): Promise<number>;
640
+ /** A session's queued messages, first to go first. */
641
+ queuedMessages(sessionId: string): Promise<QueuedMessageRow[]>;
642
+ countQueuedMessages(sessionId: string): Promise<number>;
643
+ /** Removes queued messages a turn took. */
644
+ deleteQueuedMessages(ids: readonly string[]): Promise<void>;
645
+ agentTriggers(agentId: string): Promise<AgentTriggerRow[]>;
646
+ /** One trigger's state; with `lock`, its row is locked until the transaction ends. */
647
+ agentTrigger(agentId: string, triggerId: string, options?: {
648
+ lock?: boolean;
649
+ }): Promise<AgentTriggerRow | undefined>;
650
+ /** Inserts or replaces a trigger's state (its `createdAt` is kept). */
651
+ putAgentTrigger(row: AgentTriggerRow): Promise<void>;
652
+ deleteAgentTrigger(agentId: string, triggerId: string): Promise<void>;
653
+ /** Deletes an Agent's triggers and runs. */
654
+ deleteAgentTriggers(agentId: string): Promise<void>;
655
+ /**
656
+ * Active triggers with a next fire time (due by `dueBefore`, changed since `changedSince`, when
657
+ * given), by Agent and trigger id.
658
+ */
659
+ activeTriggers(options: {
660
+ dueBefore?: string;
661
+ changedSince?: string;
662
+ after?: {
663
+ agentId: string;
664
+ triggerId: string;
665
+ };
666
+ limit: number;
667
+ }): Promise<AgentTriggerRow[]>;
668
+ /** The webhook trigger whose endpoint id is `endpointId`. */
669
+ agentTriggerByEndpoint(endpointId: string): Promise<AgentTriggerRow | undefined>;
670
+ /** The earliest next fire time of an Agent's active triggers, or `null`. */
671
+ nextWakeAt(agentId: string): Promise<string | null>;
672
+ /** Records a run; false when one with the same `runKey` exists for the Agent. */
673
+ insertTriggerRun(row: TriggerRunRow): Promise<boolean>;
674
+ triggerRunByKey(agentId: string, runKey: string): Promise<TriggerRunRow | undefined>;
675
+ updateTriggerRun(id: string, patch: Partial<Omit<TriggerRunRow, "id">>): Promise<void>;
676
+ /** An Agent's runs fired at or after `since` with one of `statuses`. */
677
+ countTriggerRuns(agentId: string, since: string, statuses: readonly TriggerRunRow["status"][]): Promise<number>;
678
+ /** An Agent's runs, newest first, before run id `before`. */
679
+ listTriggerRuns(agentId: string, options: {
680
+ triggerId?: string;
681
+ before?: string;
682
+ limit: number;
683
+ }): Promise<TriggerRunRow[]>;
684
+ /** Deletes runs fired before `before`; returns how many. */
685
+ pruneTriggerRuns(before: string): Promise<number>;
686
+ /** One memory; with `lock`, its path is locked until the transaction ends, whether or not a row has it. */
687
+ memory(agentId: string, path: string, options?: {
688
+ lock?: boolean;
689
+ }): Promise<MemoryRow | undefined>;
690
+ /**
691
+ * An Agent's memories by path: those inside `folder` (a normalised folder path, `/memories` for
692
+ * all), after path `after`; with `lock`, their rows are locked until the transaction ends.
693
+ */
694
+ memories(agentId: string, options: {
695
+ folder?: string;
696
+ after?: string;
697
+ limit?: number;
698
+ lock?: boolean;
699
+ }): Promise<MemoryRow[]>;
700
+ countMemories(agentId: string): Promise<number>;
701
+ /** An Agent's newest memories first (by `updatedAt`, then path): what the pinned index lists. */
702
+ recentMemories(agentId: string, limit: number): Promise<Pick<MemoryRow, "path" | "description" | "bytes">[]>;
703
+ /** Inserts or replaces a memory. */
704
+ putMemory(row: MemoryRow): Promise<void>;
705
+ deleteMemory(agentId: string, path: string): Promise<void>;
706
+ insertMemoryVersion(row: MemoryVersionRow): Promise<void>;
707
+ /** An Agent's memory versions, newest first, before version id `before`; `path` keeps one path's. */
708
+ memoryVersions(agentId: string, options: {
709
+ path?: string;
710
+ before?: string;
711
+ limit: number;
712
+ }): Promise<MemoryVersionRow[]>;
713
+ memoryVersion(agentId: string, id: string): Promise<MemoryVersionRow | undefined>;
714
+ /** Copies Agent `from`'s memories to new Agent `to`, each at version 1, with no history (a fork). */
715
+ copyMemories(from: string, to: string, now: string): Promise<number>;
716
+ /** Deletes an Agent's memories and their versions. */
717
+ deleteAgentMemories(agentId: string): Promise<void>;
612
718
  /** Links of one workflow session joined to their existing agent sessions, ordered by agent session id. */
613
719
  linkedSessions<S extends SessionDoc = SessionDoc>(workflowSessionId: string): Promise<LinkedSession<S>[]>;
614
720
  counts(): Promise<StoreCounts>;
@@ -794,16 +900,15 @@ export interface Tx {
794
900
  * Tenant's record rows and log heads. The Tenant moves to the next basin
795
901
  * generation and the current one is retired, so session ids it frees start again in an
796
902
  * empty basin;
797
- * - `environments`: sandbox records, Environments with their vaults, and their lifecycle
798
- * streams;
799
- * - `all`: both, plus definitions (and which definition files they use),
903
+ * - `agents`: sandbox records, Agents with their vaults, and their lifecycle streams;
904
+ * - `all`: both, plus agent manifests (and which definition files they use),
800
905
  * the model usage ledger, the model budgets and Tenant-wide artifacts. The host vault, principals, signing keys,
801
906
  * settings, audit and vault idempotency rows stay.
802
907
  */
803
908
  reset(scope: ResetScope): Promise<void>;
804
909
  }
805
- /** Which of an Environment's events to read (`Tx.environmentEvents`). */
806
- export interface EnvironmentEventsQuery {
910
+ /** Which of an Agent's events to read (`Tx.agentEvents`). */
911
+ export interface AgentEventsQuery {
807
912
  readonly fromSeq?: number;
808
913
  readonly limit?: number;
809
914
  readonly types?: readonly string[];
@@ -1,5 +1,4 @@
1
1
  export const DOC_TABLES = [
2
- "definitions",
3
2
  "sessions",
4
3
  "commands",
5
4
  "effects",
@@ -50,11 +50,11 @@ import { recoversModelCalls } from "./effects.js";
50
50
  import { contextCompacted } from "./transcript.js";
51
51
  import { slimModelEffects } from "./slim.js";
52
52
  import { applyUpdates, leanState, transcriptShadow, withTranscript, } from "./history.js";
53
- import { command } from "./commands.js";
54
- import { dropRunGrant, grantRun } from "./run-grants.js";
53
+ import { command, startQueuedTurn } from "./commands.js";
54
+ import { dropRunGrant, grantRun, rootAgentOf } from "./run-grants.js";
55
55
  import { startHeartbeat } from "../harness-api/renew.js";
56
56
  import { buildTurnStart, startSegment } from "../harness-api/start.js";
57
- import { touchEnvironment } from "./environments.js";
57
+ import { touchAgent } from "./agents.js";
58
58
  import { endTurn, pauseTurn } from "./turn-timing.js";
59
59
  import { hostTuning } from "../tuning.js";
60
60
  import { AdvanceAbort, AdvanceDeadlineError, abortKind, } from "./worker.js";
@@ -124,7 +124,10 @@ export async function advance(ctx, id, signal) {
124
124
  ctx.work.running.set(id, controller);
125
125
  ctx.work.runningTurns.set(id, taken.session.activeTurnId ?? null);
126
126
  // A harness renews the lease once it holds the run; until then, and without one, core does.
127
- const run = { agentId: taken.session.agentId, activeTurnId: taken.session.activeTurnId };
127
+ // The run token names the root agent as the engine does: the loop manifest's id, i.e. the
128
+ // agent manifest's name (protocol 16), never the Agent the session runs on. The model gate's
129
+ // usage rows and `manifest` budgets key on it.
130
+ const run = { agentId: rootAgentOf(taken.session), activeTurnId: taken.session.activeTurnId };
128
131
  const heartbeat = startHeartbeat(ctx, lease, controller, run);
129
132
  let result = DONE;
130
133
  let release = true;
@@ -181,7 +184,7 @@ export async function advance(ctx, id, signal) {
181
184
  // The Environment was used: `deleteAfter`, and a pod's idle time (D34), count from the end
182
185
  // of each segment.
183
186
  if (placed.environment !== undefined)
184
- await touchEnvironment(ctx, placed.environment);
187
+ await touchAgent(ctx, placed.environment);
185
188
  }
186
189
  return result;
187
190
  }
@@ -194,11 +197,11 @@ function podUnusable(ctx, segment) {
194
197
  return `Environment ${pod.id} is a pod Environment, and this Runtime has no sandbox pods`;
195
198
  const state = pod.pod;
196
199
  if (state.desired === "deleted")
197
- return `Environment ${pod.id} was deleted`;
200
+ return `Agent ${pod.id} was deleted`;
198
201
  if (state.observed === "lost")
199
- return `Environment ${pod.id} was lost: ${state.reason ?? "its volume is gone"}`;
202
+ return `Agent ${pod.id} was lost: ${state.reason ?? "its volume is gone"}`;
200
203
  if (state.observed === "failed")
201
- return `Environment ${pod.id} failed to start: ${state.reason ?? "its pod was not ready"}`;
204
+ return `Agent ${pod.id} failed to start: ${state.reason ?? "its pod was not ready"}`;
202
205
  return undefined;
203
206
  }
204
207
  /**
@@ -285,6 +288,10 @@ async function runRemoteSegment(ctx, lease, started, controller, run, onTaken, p
285
288
  // A new volume being seeded from a disk version takes no turn until it holds it (R2d step 3).
286
289
  if (segment.pod?.seeding)
287
290
  throw new HarnessUnavailable();
291
+ // A pod starting on a new version takes no turn until its harness joins (track T3): a start
292
+ // that fails goes back to the version it ran, and the turn's first segment re-pins to it.
293
+ if (segment.pod?.starting)
294
+ throw new HarnessUnavailable();
288
295
  const pod = segment.pod?.id;
289
296
  if (started.environmentId !== undefined)
290
297
  placed.environment = started.environmentId;
@@ -562,6 +569,9 @@ writer) {
562
569
  await t.event(id, s.activeTurnId, type, payload, writer);
563
570
  await t.put("sessions", id, current);
564
571
  await wakeWorkflowOf(ctx, t, current, s.activeTurnId, type, payload);
572
+ // Messages that waited for this turn start the next one (protocol 17).
573
+ if (await startQueuedTurn(ctx, t, current, id))
574
+ await t.put("sessions", id, current);
565
575
  return siblings;
566
576
  });
567
577
  for (const agentId of siblingCancelIds) {
@@ -636,6 +646,8 @@ async function settleFailure(ctx, lease, s, error) {
636
646
  current.activeTurnId = null;
637
647
  await t.put("sessions", id, current);
638
648
  await wakeWorkflowOf(ctx, t, current, s.activeTurnId, "turn.failed", payload);
649
+ if (await startQueuedTurn(ctx, t, current, id))
650
+ await t.put("sessions", id, current);
639
651
  });
640
652
  }
641
653
  /** Whether the session runs our harness, whose state core may store lean (R4.2). */
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Agent manifests (protocol 16, track T2): `/v1/agent-manifests/{name}`, named and versioned
3
+ * documents with what runs inside an agent's loop (`harness`) and what the Runtime provides
4
+ * around it (`runtime`). They replace agent definitions (`PUT /v1/agents/:id` before protocol
5
+ * 16) and environment manifests.
6
+ *
7
+ * - **Versions.** A save whose manifest hashes the same as the latest answers it unchanged; any
8
+ * other writes the next version. A version is never changed or deleted alone.
9
+ * - **Tracking Agents move.** Saving a version moves every Agent that tracks the manifest to it
10
+ * (track T3, `moveAgent`), in the save's transaction: at once, at its pod's next start, or once
11
+ * its required secrets are set. A pinned Agent stays, and so does one the version cannot move
12
+ * (a fixed field) or whose start failed on it. The plan counts both.
13
+ * - **Both sections at once.** The Runtime sees both sections, so it checks them against each
14
+ * other (`sectionGaps`): every gap is named in one `422 manifest_inconsistent`, which is what
15
+ * `requires` checked when a session opened before protocol 16. Each section's own checks run
16
+ * too: the harness's (no code tools, no approvals, HTTP tool timeouts, the skill files) and the
17
+ * runtime's (the Tenant's limits, its files).
18
+ * - **Plan and drift.** `?dryRun=true` answers what a save would do and saves nothing: the
19
+ * changes from the latest by section, every reason the Runtime would refuse it, warnings, the
20
+ * Agents it moves and how many stay on older versions. `If-Match: <version>` refuses
21
+ * (`412 manifest_changed`) a save whose latest version moved since the client read it; `0` asks
22
+ * for a manifest that does not exist yet.
23
+ * - **Every client is equal** (Q12): a version records who saved it (`savedBy`).
24
+ */
25
+ import { type AgentManifestChange, type AgentManifestPlan, type AgentManifestV8, type AgentManifestVersions, type AgentManifestView, type PutAgentManifestRequest, type SaveAgentManifestResponse } from "@nylorun/core/contracts";
26
+ import { type RecipeRequest } from "../sandbox/resolve.js";
27
+ import type { AuthScope, TenantContext } from "./context.js";
28
+ /** What a manifest's runtime section asks of an Agent's recipe, with the harness its loop names. */
29
+ export declare function manifestRecipeRequest(manifest: Pick<AgentManifestV8, "harness" | "runtime">): RecipeRequest;
30
+ /** The hash a manifest's version records: equal manifests hash the same. */
31
+ export declare function agentManifestHash(manifest: AgentManifestV8): string;
32
+ /** The owner a version's definition files are recorded under, for the sweep. */
33
+ export declare function manifestFileOwner(name: string): string;
34
+ /** Each field that differs between `before` and `after`, by path; arrays compare whole. */
35
+ export declare function manifestChanges(before: unknown, after: unknown, path?: string): {
36
+ path: string;
37
+ from?: unknown;
38
+ to?: unknown;
39
+ }[];
40
+ /**
41
+ * The changes from `before` to `after` by section: `manifest` for the top-level fields, else
42
+ * `harness` or `runtime` with the path inside it. A section added or removed whole is one change.
43
+ */
44
+ export declare function sectionChanges(before: Partial<AgentManifestV8> | undefined, after: AgentManifestV8): AgentManifestChange[];
45
+ /**
46
+ * `PUT /v1/agent-manifests/{name}`: saves `body` as manifest `name`'s next version, or answers
47
+ * the latest unchanged; with `dryRun`, the plan of that save and nothing saved.
48
+ */
49
+ export declare function saveAgentManifest(ctx: TenantContext, name: string, body: PutAgentManifestRequest, scope: AuthScope, options: {
50
+ dryRun: true;
51
+ ifMatch?: number;
52
+ }): Promise<AgentManifestPlan>;
53
+ export declare function saveAgentManifest(ctx: TenantContext, name: string, body: PutAgentManifestRequest, scope: AuthScope, options?: {
54
+ dryRun?: false;
55
+ ifMatch?: number;
56
+ }): Promise<SaveAgentManifestResponse>;
57
+ /** `GET /v1/agent-manifests/{name}` (the latest) and `.../versions/{n}`. */
58
+ export declare function getAgentManifest(ctx: TenantContext, name: string, version?: number): Promise<AgentManifestView>;
59
+ /** `GET /v1/agent-manifests`: each manifest's latest version. */
60
+ export declare function listAgentManifests(ctx: TenantContext): Promise<{
61
+ manifests: AgentManifestView[];
62
+ }>;
63
+ /** `GET /v1/agent-manifests/{name}/versions`: every version, newest first. */
64
+ export declare function agentManifestVersions(ctx: TenantContext, name: string): Promise<AgentManifestVersions>;
65
+ /**
66
+ * `DELETE /v1/agent-manifests/{name}`: deletes every version, refused while any Agent was made
67
+ * from one (`409 manifest_in_use`): the Agent names the version it runs.
68
+ */
69
+ export declare function deleteAgentManifest(ctx: TenantContext, name: string): Promise<{
70
+ name: string;
71
+ deleted: boolean;
72
+ }>;