@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
@@ -225,6 +225,48 @@
225
225
  "when": 1792094620175,
226
226
  "tag": "0031_protocol_15_mcp_snapshot",
227
227
  "breakpoints": true
228
+ },
229
+ {
230
+ "idx": 32,
231
+ "version": "7",
232
+ "when": 1792098220175,
233
+ "tag": "0032_agents",
234
+ "breakpoints": true
235
+ },
236
+ {
237
+ "idx": 33,
238
+ "version": "7",
239
+ "when": 1792161078177,
240
+ "tag": "0033_agent_versions",
241
+ "breakpoints": true
242
+ },
243
+ {
244
+ "idx": 34,
245
+ "version": "7",
246
+ "when": 1792163689759,
247
+ "tag": "0034_protocol_17_session_queue",
248
+ "breakpoints": true
249
+ },
250
+ {
251
+ "idx": 35,
252
+ "version": "7",
253
+ "when": 1792164194039,
254
+ "tag": "0035_t4_triggers",
255
+ "breakpoints": true
256
+ },
257
+ {
258
+ "idx": 36,
259
+ "version": "7",
260
+ "when": 1792172016681,
261
+ "tag": "0036_t5_memories",
262
+ "breakpoints": true
263
+ },
264
+ {
265
+ "idx": 37,
266
+ "version": "7",
267
+ "when": 1792238141315,
268
+ "tag": "0037_model_usage_cost_split",
269
+ "breakpoints": true
228
270
  }
229
271
  ]
230
272
  }
@@ -11,7 +11,7 @@ import { database, driverError } from "./db.js";
11
11
  import { createPostgresReadClient } from "./connect.js";
12
12
  import { hostTuning } from "../../tuning.js";
13
13
  import { toolCallDuration, toolCallStatus } from "../../harness-api/tool-status.js";
14
- import { effects, artifacts, modelUsage, environments, sandboxes, sessions, sessionEvents, tenantSettings, } from "./schema.js";
14
+ import { effects, artifacts, modelUsage, sandboxes, sessions, sessionEvents, tenantSettings, } from "./schema.js";
15
15
  const sessionFields = {
16
16
  id: sessions.id,
17
17
  agentId: sessions.agentId,
@@ -19,11 +19,30 @@ const sessionFields = {
19
19
  status: sessions.status,
20
20
  activeTurnId: sql `${sessions.body}->>'activeTurnId'`,
21
21
  lastTurnId: sql `${sessions.body}->>'lastTurnId'`,
22
- environmentId: sessions.environmentId,
23
22
  createdAt: sessions.createdAt,
24
23
  };
24
+ /** Rows whose Agent id an Agent grant (`*`, an id, or a `p/*` prefix) reaches; none reach nothing. */
25
+ function grantsWhere(column, grants) {
26
+ if (grants.includes("*"))
27
+ return sql `true`;
28
+ if (grants.length === 0)
29
+ return sql `false`;
30
+ return or(...grants.map((grant) => grant.endsWith("/*") ? sql `starts_with(${column}, ${grant.slice(0, -1)})` : eq(column, grant)));
31
+ }
25
32
  function accessWhere(access) {
26
- return and(access.owner === undefined ? undefined : eq(sessions.ownerUserId, access.owner), access.agents === undefined ? undefined : inArray(sessions.agentId, [...access.agents]));
33
+ return and(access.owner === undefined ? undefined : eq(sessions.ownerUserId, access.owner), access.agents === undefined ? undefined : grantsWhere(sessions.agentId, access.agents));
34
+ }
35
+ /** A row's cost by token kind, when the adapter kept it (migration 0037). */
36
+ function costSplitOf(row) {
37
+ const { costInputUsd, costCacheReadUsd, costCacheWriteUsd, costOutputUsd } = row;
38
+ if (costInputUsd === null || costCacheReadUsd === null || costCacheWriteUsd === null || costOutputUsd === null)
39
+ return null;
40
+ return {
41
+ input: costInputUsd,
42
+ cacheRead: costCacheReadUsd,
43
+ cacheWrite: costCacheWriteUsd,
44
+ output: costOutputUsd,
45
+ };
27
46
  }
28
47
  function publicCall(row) {
29
48
  return {
@@ -31,10 +50,12 @@ function publicCall(row) {
31
50
  effectId: row.effectKey,
32
51
  sessionId: row.sessionId,
33
52
  turnId: row.turnId,
34
- agentId: row.agentId,
53
+ manifestName: row.manifestName,
35
54
  provider: row.provider,
36
55
  model: row.model,
37
56
  at: row.createdAt,
57
+ startedAt: row.startedAt,
58
+ endedAt: row.endedAt,
38
59
  outcome: "completed",
39
60
  usage: {
40
61
  inputTokens: row.inputTokens,
@@ -47,6 +68,7 @@ function publicCall(row) {
47
68
  duplicate: row.duplicate,
48
69
  tokensReported: row.tokensReported,
49
70
  costKnown: row.costKnown,
71
+ costSplit: costSplitOf(row),
50
72
  },
51
73
  };
52
74
  }
@@ -166,9 +188,7 @@ export function createPostgresReadStore(source, tenantId) {
166
188
  const rows = await tx
167
189
  .select(fields)
168
190
  .from(sessions)
169
- .where(and(accessWhere(access), position, filters.agentId === undefined ? undefined : eq(sessions.agentId, filters.agentId), filters.status === undefined ? undefined : eq(sessions.status, filters.status), filters.environmentId === undefined
170
- ? undefined
171
- : eq(sessions.environmentId, filters.environmentId), filters.ownerUserId === undefined
191
+ .where(and(accessWhere(access), position, filters.agentId === undefined ? undefined : eq(sessions.agentId, filters.agentId), filters.status === undefined ? undefined : eq(sessions.status, filters.status), filters.manifest === undefined ? undefined : eq(sessions.manifestName, filters.manifest), filters.ownerUserId === undefined
172
192
  ? undefined
173
193
  : eq(sessions.ownerUserId, filters.ownerUserId)))
174
194
  .orderBy(sql `${sessions.createdAt} desc nulls last`, desc(sessions.id))
@@ -189,8 +209,8 @@ export function createPostgresReadStore(source, tenantId) {
189
209
  .select({
190
210
  sessionId: sessions.id,
191
211
  agentId: sessions.agentId,
212
+ definition: sql `${sessions.body}->'definition'`,
192
213
  manifestHash: sql `${sessions.body}->>'manifestHash'`,
193
- implementationVersion: sql `${sessions.body}->>'implementationVersion'`,
194
214
  manifest: sql `${sessions.body}->'manifest'`,
195
215
  })
196
216
  .from(sessions)
@@ -220,11 +240,26 @@ export function createPostgresReadStore(source, tenantId) {
220
240
  unpricedCalls: sql `count(*) filter (where ${modelUsage.costKnown} = false)`.mapWith(Number),
221
241
  unreportedCalls: sql `count(*) filter (where ${modelUsage.tokensReported} = false)`.mapWith(Number),
222
242
  unknownQualityCalls: sql `count(*) filter (where ${modelUsage.tokensReported} is null or ${modelUsage.costKnown} is null)`.mapWith(Number),
243
+ costInput: sum(modelUsage.costInputUsd),
244
+ costCacheRead: sum(modelUsage.costCacheReadUsd),
245
+ costCacheWrite: sum(modelUsage.costCacheWriteUsd),
246
+ costOutput: sum(modelUsage.costOutputUsd),
247
+ splitCalls: sql `count(${modelUsage.costInputUsd})`.mapWith(Number),
248
+ // The gate's timing is ISO text; a row timed before migration 0022 has none.
249
+ modelTimeMs: sql `coalesce(round(sum(extract(epoch from (${modelUsage.endedAt}::timestamptz - ${modelUsage.startedAt}::timestamptz)) * 1000)), 0)`.mapWith(Number),
250
+ timedCalls: sql `count(*) filter (where ${modelUsage.startedAt} is not null and ${modelUsage.endedAt} is not null)`.mapWith(Number),
223
251
  })
224
252
  .from(modelUsage)
225
253
  .where(and(eq(modelUsage.sessionId, id), turnId === undefined ? undefined : eq(modelUsage.turnId, turnId)));
254
+ const { costInput, costCacheRead, costCacheWrite, costOutput, ...rest } = totals;
226
255
  return {
227
- ...totals,
256
+ ...rest,
257
+ costSplit: {
258
+ input: costInput,
259
+ cacheRead: costCacheRead,
260
+ cacheWrite: costCacheWrite,
261
+ output: costOutput,
262
+ },
228
263
  sessionId: id,
229
264
  turnId: turnId ?? null,
230
265
  asOf: new Date().toISOString(),
@@ -304,83 +339,5 @@ export function createPostgresReadStore(source, tenantId) {
304
339
  asOf: new Date().toISOString(),
305
340
  };
306
341
  }),
307
- environments: (labels, page, access, grants) => read(async (tx) => {
308
- const cursor = readCursor(tenantId, "environments", labels);
309
- const key = keyOf(cursor.decode(page.cursor), 1);
310
- const allowed = grants === undefined
311
- ? undefined
312
- : or(...grants.map((grant) => grant.endsWith("/*")
313
- ? sql `starts_with(${environments.id}, ${grant.slice(0, -1)})`
314
- : eq(environments.id, grant)));
315
- const rows = await tx
316
- .select()
317
- .from(environments)
318
- .where(and(grants?.length === 0 ? sql `false` : allowed, key ? gt(environments.id, key[0]) : undefined, or(isNull(environments.desired), ne(environments.desired, "deleted")), ...Object.entries(labels).map(([k, v]) => sql `${environments.labels}::jsonb->>${k} = ${v}`)))
319
- .orderBy(asc(environments.id))
320
- .limit(page.limit + 1);
321
- const tenantLimits = await readTenantLimits({
322
- getSetting: async (setting) => (await tx.select({ value: tenantSettings.value }).from(tenantSettings).where(eq(tenantSettings.key, setting)))[0]
323
- ?.value,
324
- });
325
- const items = [];
326
- for (const row of rows.slice(0, page.limit)) {
327
- const [related] = await tx
328
- .select({
329
- items: sql `coalesce(json_agg(json_build_object('id', ${sessions.id}, 'activeTurnId', ${sessions.body}->>'activeTurnId') order by ${sessions.id}), '[]'::json)`,
330
- })
331
- .from(sessions)
332
- .where(and(eq(sessions.environmentId, row.id), accessWhere(access)));
333
- const [compute] = await tx
334
- .select({ body: sandboxes.body })
335
- .from(sandboxes)
336
- .where(eq(sandboxes.id, sandboxWorkspaceKey(tenantId, row.id)))
337
- .limit(1);
338
- const isPod = row.kind === "pod";
339
- items.push({
340
- id: row.id,
341
- kind: row.kind,
342
- labels: row.labels,
343
- manifest: row.recipe,
344
- ...(row.manifestName === null ? {} : { manifestName: row.manifestName }),
345
- ...(row.manifestVersion === null ? {} : { manifestVersion: row.manifestVersion }),
346
- ...(row.manifestHash === null ? {} : { manifestHash: row.manifestHash }),
347
- limits: limitsInForce(tenantLimits, row.recipe.limits),
348
- ...(row.forkedFrom ? { forkedFrom: row.forkedFrom } : {}),
349
- version: row.version,
350
- appliedVersion: row.appliedVersion,
351
- ownerUserId: row.ownerUserId,
352
- state: isPod
353
- ? row.observed === "running"
354
- ? "running"
355
- : row.observed === "creating"
356
- ? "creating"
357
- : "stopped"
358
- : row.kind === "none"
359
- ? "ready"
360
- : (compute?.body?.state ?? "ready"),
361
- ...(isPod
362
- ? {
363
- pod: {
364
- desired: row.desired,
365
- observed: row.observed,
366
- volumeGeneration: row.volumeGen,
367
- hostEpoch: row.hostEpoch,
368
- ...(row.reason ? { reason: row.reason } : {}),
369
- ...(row.imageDigest ? { imageDigest: row.imageDigest } : {}),
370
- },
371
- }
372
- : {}),
373
- lastUsedAt: new Date(row.lastUsedAt).toISOString(),
374
- sessions: related.items,
375
- createdAt: row.createdAt,
376
- updatedAt: row.updatedAt,
377
- });
378
- }
379
- const last = items.at(-1);
380
- return {
381
- environments: items,
382
- nextCursor: rows.length > page.limit && last ? cursor.encode([last.id]) : null,
383
- };
384
- }),
385
342
  };
386
343
  }
@@ -1,9 +1,9 @@
1
- import type { RecordWriter, EnvironmentRecordWriter } from "../../record/index.js";
1
+ import type { RecordWriter, AgentRecordWriter } from "../../record/index.js";
2
2
  import type { Transaction } from "./db.js";
3
3
  /**
4
- * The Environment stream writer of transaction `db` (`record/environment.ts`): the only inserts
5
- * into `environment_events`. The caller holds the Environment row's lock, which orders its events.
4
+ * The Agent stream writer of transaction `db` (`record/agent.ts`): the only inserts into
5
+ * `agent_events`. The caller holds the Agent row's lock, which orders its events.
6
6
  */
7
- export declare function postgresEnvironmentRecordWriter(db: Transaction): EnvironmentRecordWriter;
7
+ export declare function postgresAgentRecordWriter(db: Transaction): AgentRecordWriter;
8
8
  /** The record writer of transaction `db`. */
9
9
  export declare function postgresRecordWriter(db: Transaction): RecordWriter;
@@ -5,22 +5,22 @@
5
5
  * run in the store's transaction under the caller's session row lock.
6
6
  */
7
7
  import { eq, sql } from "drizzle-orm";
8
- import { environmentEvents, sessionEvents, sessionLogHeads, tenant } from "./schema.js";
8
+ import { agentEvents, sessionEvents, sessionLogHeads, tenant } from "./schema.js";
9
9
  /**
10
- * The Environment stream writer of transaction `db` (`record/environment.ts`): the only inserts
11
- * into `environment_events`. The caller holds the Environment row's lock, which orders its events.
10
+ * The Agent stream writer of transaction `db` (`record/agent.ts`): the only inserts into
11
+ * `agent_events`. The caller holds the Agent row's lock, which orders its events.
12
12
  */
13
- export function postgresEnvironmentRecordWriter(db) {
13
+ export function postgresAgentRecordWriter(db) {
14
14
  return {
15
- async nextSeq(environmentId) {
15
+ async nextSeq(agentId) {
16
16
  const [row] = await db
17
- .select({ next: sql `coalesce(max(${environmentEvents.seq}) + 1, 0)`.mapWith(Number) })
18
- .from(environmentEvents)
19
- .where(eq(environmentEvents.environmentId, environmentId));
17
+ .select({ next: sql `coalesce(max(${agentEvents.seq}) + 1, 0)`.mapWith(Number) })
18
+ .from(agentEvents)
19
+ .where(eq(agentEvents.agentId, agentId));
20
20
  return row?.next ?? 0;
21
21
  },
22
22
  async insert(row) {
23
- await db.insert(environmentEvents).values(row);
23
+ await db.insert(agentEvents).values(row);
24
24
  },
25
25
  };
26
26
  }