@nylorun/runtime 0.42.0-beta → 0.44.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.
- package/CHANGELOG.md +53 -0
- package/dist/api/a2a/endpoint.js +1 -1
- package/dist/api/a2a/push.js +14 -1
- package/dist/api/a2a/routes.js +40 -26
- package/dist/api/a2a/tasks.d.ts +14 -0
- package/dist/api/a2a/tasks.js +42 -0
- package/dist/api/components.d.ts +1109 -188
- package/dist/artifacts/disk.js +7 -0
- package/dist/harness/main.js +8 -4
- package/dist/harness-api/record.js +20 -0
- package/dist/management-openapi.json +15 -4
- package/dist/openapi.json +460 -7
- package/dist/sandbox/pods/lifecycle.d.ts +5 -1
- package/dist/sandbox/pods/lifecycle.js +8 -0
- package/dist/sandbox/pods/network-gate.d.ts +6 -0
- package/dist/sandbox/pods/network-gate.js +20 -4
- package/dist/store/postgres/drizzle/0045_session_queue_delivery.sql +2 -0
- package/dist/store/postgres/drizzle/meta/_journal.json +7 -0
- package/dist/store/postgres/schema.d.ts +19 -1
- package/dist/store/postgres/schema.js +11 -2
- package/dist/store/postgres/store.js +11 -0
- package/dist/store/types.d.ts +11 -1
- package/dist/tenant/commands.d.ts +55 -10
- package/dist/tenant/commands.js +212 -45
- package/dist/tenant/context.d.ts +11 -0
- package/dist/tenant/sweep.js +44 -15
- package/dist/tuning.d.ts +3 -0
- package/dist/tuning.js +12 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +3 -3
package/dist/tenant/sweep.js
CHANGED
|
@@ -43,7 +43,11 @@
|
|
|
43
43
|
* the delivery after commit, sends), and configs of tasks long finished are deleted. A push
|
|
44
44
|
* row that fails is retried with the Host tuning's `a2a.pushRetry` and dropped once it is
|
|
45
45
|
* `a2a.pushMaxAgeMs` old, never parked: the change feed covers what it said.
|
|
46
|
-
* 7. **
|
|
46
|
+
* 7. **Queued messages** (Host feature `queue-recovery`): at most every `sweep.queueRetryMs`, the
|
|
47
|
+
* turn start of every session queue an Agent's refusal left waiting is tried again
|
|
48
|
+
* (`retryQueuedStarts`); a message past the Runtime limit `queuedStartMs` fails
|
|
49
|
+
* (`queue.failed`). The end of a disk copy tries its Agent's sessions at once.
|
|
50
|
+
* 8. **Hooks.** Callbacks registered with `ctx.onSweep`.
|
|
47
51
|
*
|
|
48
52
|
* Every step runs one transaction per session it changes (a linked agent and its workflow
|
|
49
53
|
* share one, child first), so the sweep follows the lock order in `store/types.ts`. A failing
|
|
@@ -51,12 +55,14 @@
|
|
|
51
55
|
* reports it.
|
|
52
56
|
*/
|
|
53
57
|
import { sweepUnusedAgents } from "./agents.js";
|
|
58
|
+
import { retryQueuedStarts } from "./commands.js";
|
|
54
59
|
import { reconcileTriggers } from "./triggers.js";
|
|
55
60
|
import { streamMissedRuns } from "./runs-stream.js";
|
|
56
61
|
import { sweepPendingSeeds } from "../artifacts/disk.js";
|
|
57
62
|
import { pendingAgentEffects, reconcilePendingAgentEffect, } from "../core/flow-host.js";
|
|
58
63
|
import { hostTuning } from "../tuning.js";
|
|
59
|
-
import { sweepStartChecks } from "./agent-versions.js";
|
|
64
|
+
import { idleMsOf, sweepStartChecks } from "./agent-versions.js";
|
|
65
|
+
import { readSandboxConfig } from "../sandbox/tenant-config.js";
|
|
60
66
|
import { pumpPushes, pushRetry } from "../api/a2a/push.js";
|
|
61
67
|
/*
|
|
62
68
|
* The sweep's timings are the Host tuning's `sweep` group (`tuning.ts`):
|
|
@@ -69,6 +75,7 @@ import { pumpPushes, pushRetry } from "../api/a2a/push.js";
|
|
|
69
75
|
* - `drainBudgetMs`: how long one pass may spend draining the outbox, and paging through
|
|
70
76
|
* orphaned sessions. A backlog is worked off over several passes rather than holding one (and
|
|
71
77
|
* with it the Tenant's sweep object in the execution) for long.
|
|
78
|
+
* - `queueRetryMs`: how often the queues an Agent's refusal left waiting are tried again.
|
|
72
79
|
* - `batchSize`, `signalRetentionMs`, `outboxAttempts`, `outboxRetry`, `stalePodMs`.
|
|
73
80
|
*/
|
|
74
81
|
/**
|
|
@@ -88,6 +95,7 @@ export async function sweep(ctx) {
|
|
|
88
95
|
pass.orphansAfter !== undefined ||
|
|
89
96
|
now.getTime() - pass.orphansAt >= hostTuning().sweep.orphanScanMs;
|
|
90
97
|
const checkPods = pass.podsAt === undefined || now.getTime() - pass.podsAt >= hostTuning().sweep.orphanScanMs;
|
|
98
|
+
const retryQueues = pass.queuesAt === undefined || now.getTime() - pass.queuesAt >= hostTuning().sweep.queueRetryMs;
|
|
91
99
|
const steps = [
|
|
92
100
|
["outbox", () => deliverOutbox(ctx, first ? 0 : hostTuning().sweep.outboxGraceMs)],
|
|
93
101
|
["linked", () => reconcileLinkedAgents(ctx)],
|
|
@@ -142,6 +150,17 @@ export async function sweep(ctx) {
|
|
|
142
150
|
"signals",
|
|
143
151
|
() => ctx.store.tx((t) => t.pruneSignals(new Date(now.getTime() - hostTuning().sweep.signalRetentionMs))),
|
|
144
152
|
],
|
|
153
|
+
...(retryQueues
|
|
154
|
+
? [
|
|
155
|
+
[
|
|
156
|
+
"queues",
|
|
157
|
+
async () => {
|
|
158
|
+
pass.queuesAt = now.getTime();
|
|
159
|
+
await retryQueuedStarts(ctx, { now, batchSize: hostTuning().sweep.batchSize });
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
]
|
|
163
|
+
: []),
|
|
145
164
|
...[...ctx.sweepHooks].map((hook) => ["hook", hook]),
|
|
146
165
|
];
|
|
147
166
|
let failure;
|
|
@@ -287,7 +306,8 @@ export async function wakeOrphanedSessions(ctx, now = new Date(), after, budgetM
|
|
|
287
306
|
}
|
|
288
307
|
/**
|
|
289
308
|
* Pod sandboxes (F7.2) whose change has not finished (creating, deleting, an old volume still
|
|
290
|
-
* to delete, an expiry not yet recorded),
|
|
309
|
+
* to delete, an expiry not yet recorded), that should run but whose engine is not connected, or
|
|
310
|
+
* that run past their idle limit (a wake that armed no idle timer: the reconcile arms it),
|
|
291
311
|
* and whose row has not moved for `sweep.stalePodMs` (a minute), get a reconcile: a pod or volume deleted outside
|
|
292
312
|
* the Runtime is found, and a change goes on whose reconcile the execution itself lost (its
|
|
293
313
|
* retry timer, an invocation an operator killed, Restate's state wiped) or whose outbox row
|
|
@@ -296,18 +316,27 @@ export async function wakeOrphanedSessions(ctx, now = new Date(), after, budgetM
|
|
|
296
316
|
async function reconcileStalePods(ctx, now) {
|
|
297
317
|
if (!ctx.pods)
|
|
298
318
|
return;
|
|
299
|
-
const stale = await ctx.store.tx(async (t) =>
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
pod.
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
319
|
+
const stale = await ctx.store.tx(async (t) => {
|
|
320
|
+
const config = await readSandboxConfig(t);
|
|
321
|
+
return (await t.listEnvironments()).filter((row) => {
|
|
322
|
+
const pod = row.pod;
|
|
323
|
+
if (!pod || now.getTime() - Date.parse(row.updatedAt) < hostTuning().sweep.stalePodMs)
|
|
324
|
+
return false;
|
|
325
|
+
return (pod.desired === "deleted" ||
|
|
326
|
+
pod.retiring !== undefined ||
|
|
327
|
+
pod.observed === "creating" ||
|
|
328
|
+
pod.observed === "deleting" ||
|
|
329
|
+
(pod.desired === "suspended" && pod.observed !== "suspended") ||
|
|
330
|
+
// Running, but its engine is not connected: the pod may be gone, or its volume.
|
|
331
|
+
(pod.desired === "running" && pod.observed === "running" && !ctx.harness.hosting(row.id)) ||
|
|
332
|
+
// Running past its idle limit: its idle timer is missing (or a turn holds it, which the
|
|
333
|
+
// reconcile leaves alone).
|
|
334
|
+
(pod.desired === "running" &&
|
|
335
|
+
pod.observed === "running" &&
|
|
336
|
+
now.getTime() - Date.parse(pod.lastActiveAt ?? row.createdAt) >
|
|
337
|
+
idleMsOf(config, row) + hostTuning().sweep.stalePodMs));
|
|
338
|
+
});
|
|
339
|
+
});
|
|
311
340
|
for (const row of stale)
|
|
312
341
|
await ctx.sandboxSignal(row.id, { kind: "reconcile" });
|
|
313
342
|
}
|
package/dist/tuning.d.ts
CHANGED
|
@@ -121,6 +121,7 @@ export declare const HostTuningSchema: z.ZodObject<{
|
|
|
121
121
|
maxMs: z.ZodDefault<z.ZodNumber>;
|
|
122
122
|
}, z.core.$strict>>;
|
|
123
123
|
stalePodMs: z.ZodDefault<z.ZodNumber>;
|
|
124
|
+
queueRetryMs: z.ZodDefault<z.ZodNumber>;
|
|
124
125
|
}, z.core.$strict>>;
|
|
125
126
|
a2a: z.ZodPrefault<z.ZodObject<{
|
|
126
127
|
pushRetry: z.ZodPrefault<z.ZodObject<{
|
|
@@ -297,6 +298,8 @@ export declare const HostTuningSchema: z.ZodObject<{
|
|
|
297
298
|
networkProbeMs: z.ZodDefault<z.ZodNumber>;
|
|
298
299
|
networkPauseMs: z.ZodDefault<z.ZodNumber>;
|
|
299
300
|
networkConfirmations: z.ZodDefault<z.ZodNumber>;
|
|
301
|
+
wakeNetworkProbeMs: z.ZodDefault<z.ZodNumber>;
|
|
302
|
+
wakeNetworkConfirmations: z.ZodDefault<z.ZodNumber>;
|
|
300
303
|
setupRetryPollMs: z.ZodDefault<z.ZodNumber>;
|
|
301
304
|
setupAfterSeedPollMs: z.ZodDefault<z.ZodNumber>;
|
|
302
305
|
setupReportTailChars: z.ZodDefault<z.ZodNumber>;
|
package/dist/tuning.js
CHANGED
|
@@ -207,6 +207,11 @@ export const HostTuningSchema = z
|
|
|
207
207
|
outboxRetry: backoff(5_000, 10 * MINUTE),
|
|
208
208
|
/** How long a pod row may go unchanged before the sweep checks it. */
|
|
209
209
|
stalePodMs: ms(MINUTE),
|
|
210
|
+
/**
|
|
211
|
+
* How often the sweep tries again the turn start of queued messages their Agent refused
|
|
212
|
+
* (Host feature `queue-recovery`); they fail after the Runtime limit `queuedStartMs`.
|
|
213
|
+
*/
|
|
214
|
+
queueRetryMs: ms(30_000),
|
|
210
215
|
}),
|
|
211
216
|
/** The A2A server's push notifications (Host feature `a2a-profile-v2`). */
|
|
212
217
|
a2a: group({
|
|
@@ -495,6 +500,13 @@ export const HostTuningSchema = z
|
|
|
495
500
|
networkProbeMs: ms(1_000),
|
|
496
501
|
networkPauseMs: ms(250, 0),
|
|
497
502
|
networkConfirmations: count(3),
|
|
503
|
+
/**
|
|
504
|
+
* The same check on a wake (the disk already holds the engine's volume id): each probe, and
|
|
505
|
+
* the failed probes in a row that prove an address blocked. A probe that connects turns the
|
|
506
|
+
* wake's check into the full one.
|
|
507
|
+
*/
|
|
508
|
+
wakeNetworkProbeMs: ms(150),
|
|
509
|
+
wakeNetworkConfirmations: count(1),
|
|
498
510
|
/** Environment setup: how often a failed setup is checked for a retry, and after a seed. */
|
|
499
511
|
setupRetryPollMs: ms(5_000),
|
|
500
512
|
setupAfterSeedPollMs: ms(1_000),
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const RUNTIME_VERSION = "0.
|
|
1
|
+
export declare const RUNTIME_VERSION = "0.44.0-beta";
|
package/dist/version.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// Kept in step with package.json by runtime/server/scripts/check-package.mjs, which runs in npm run check.
|
|
2
2
|
// release:prepare also rewrites this when it bumps @nylorun/runtime.
|
|
3
|
-
export const RUNTIME_VERSION = "0.
|
|
3
|
+
export const RUNTIME_VERSION = "0.44.0-beta";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nylorun/runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0-beta",
|
|
4
4
|
"description": "Nylorun Runtime: the agent execution Host on Postgres, Restate and S2, and model providers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"@hono/node-server": "^2.1.5",
|
|
66
66
|
"@hono/zod-openapi": "^1.6.3",
|
|
67
67
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
68
|
-
"@nylorun/core": "0.
|
|
69
|
-
"@nylorun/harness": "0.
|
|
68
|
+
"@nylorun/core": "0.38.0-beta",
|
|
69
|
+
"@nylorun/harness": "0.34.1-beta",
|
|
70
70
|
"@restatedev/restate-sdk": "1.17.3",
|
|
71
71
|
"@restatedev/restate-sdk-clients": "1.17.3",
|
|
72
72
|
"@s2-dev/streamstore": "0.28.0",
|