memeloop 0.2.8 → 0.2.9

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 (36) hide show
  1. package/dist/{chunk-NVJCRIEK.js → chunk-34B7MUI6.js} +2 -2
  2. package/dist/{chunk-DACM5AMS.js → chunk-7W4FMKMO.js} +190 -56
  3. package/dist/chunk-7W4FMKMO.js.map +1 -0
  4. package/dist/{chunk-OD6U6VAR.js → chunk-GH5RDPLJ.js} +2 -2
  5. package/dist/{chunk-OD6U6VAR.js.map → chunk-GH5RDPLJ.js.map} +1 -1
  6. package/dist/device-network/cloudDeviceFetchClient.d.ts +9 -7
  7. package/dist/device-network/cloudDeviceFetchClient.d.ts.map +1 -1
  8. package/dist/device-network/deviceCloudConnectionCoordinator.d.ts +5 -5
  9. package/dist/device-network/deviceCloudConnectionCoordinator.d.ts.map +1 -1
  10. package/dist/device-network/deviceOrchestrationTransport.d.ts +7 -0
  11. package/dist/device-network/deviceOrchestrationTransport.d.ts.map +1 -1
  12. package/dist/device-network/standardDeviceCloudConnectionAdapter.d.ts +16 -8
  13. package/dist/device-network/standardDeviceCloudConnectionAdapter.d.ts.map +1 -1
  14. package/dist/device-network/types.d.ts +4 -2
  15. package/dist/device-network/types.d.ts.map +1 -1
  16. package/dist/device-network-portable.cjs +190 -55
  17. package/dist/device-network-portable.cjs.map +1 -1
  18. package/dist/device-network-portable.js +189 -55
  19. package/dist/device-network-portable.js.map +1 -1
  20. package/dist/device-network.cjs +190 -55
  21. package/dist/device-network.cjs.map +1 -1
  22. package/dist/device-network.js +4 -2
  23. package/dist/index.cjs +488 -180
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.js +302 -127
  26. package/dist/index.js.map +1 -1
  27. package/dist/loop-api.cjs +1 -1
  28. package/dist/loop-api.cjs.map +1 -1
  29. package/dist/loop-api.js +1 -1
  30. package/dist/mobile.cjs.map +1 -1
  31. package/dist/orchestration/externalOrchestrationController.d.ts.map +1 -1
  32. package/dist/orchestration/workloadExecutionController.d.ts.map +1 -1
  33. package/dist/plugin/loader.d.ts +1 -1
  34. package/package.json +2 -1
  35. package/dist/chunk-DACM5AMS.js.map +0 -1
  36. /package/dist/{chunk-NVJCRIEK.js.map → chunk-34B7MUI6.js.map} +0 -0
package/dist/index.js CHANGED
@@ -73,7 +73,7 @@ import {
73
73
  runAgentToolLoopTurn,
74
74
  saveUserPermissions,
75
75
  validatePluginManifest
76
- } from "./chunk-OD6U6VAR.js";
76
+ } from "./chunk-GH5RDPLJ.js";
77
77
  import {
78
78
  AGENT_AGENT_LOOP_ID,
79
79
  AGENT_TOOL_LOOP_ID,
@@ -262,7 +262,7 @@ import {
262
262
  import {
263
263
  MemoryDeviceNetworkService,
264
264
  syncCloudDevices
265
- } from "./chunk-NVJCRIEK.js";
265
+ } from "./chunk-34B7MUI6.js";
266
266
  import {
267
267
  ChatSyncEngine,
268
268
  CloudDeviceFetchClient,
@@ -275,6 +275,7 @@ import {
275
275
  DEVICE_CONNECTION_GRANT_MAX_TTL_MS,
276
276
  DEVICE_CONNECTION_GRANT_SIGNATURE_DOMAIN,
277
277
  DEVICE_GRANT_MAX_CLOCK_SKEW_MS,
278
+ DEVICE_ORCHESTRATION_FRAME_LIMITS,
278
279
  DEVICE_ORCHESTRATION_PROTOCOL,
279
280
  DEVICE_PAIRING_INVITE_MAX_CLOCK_SKEW_MS,
280
281
  DEVICE_PAIRING_INVITE_PROTOCOL,
@@ -330,7 +331,7 @@ import {
330
331
  reconcileCloudDeviceDirectory,
331
332
  versionVectorCoversRange,
332
333
  versionVectorKey
333
- } from "./chunk-DACM5AMS.js";
334
+ } from "./chunk-7W4FMKMO.js";
334
335
  import {
335
336
  DEVICE_HEARTBEAT_DEFAULT_MAX_CLOCK_SKEW_MS,
336
337
  DEVICE_HEARTBEAT_LIMITS,
@@ -5870,10 +5871,54 @@ function createExternalOrchestrationController(store, options) {
5870
5871
  const now = options.now ?? (() => /* @__PURE__ */ new Date());
5871
5872
  const onError = options.onError ?? (() => {
5872
5873
  });
5873
- const active = /* @__PURE__ */ new Set();
5874
+ const active = /* @__PURE__ */ new Map();
5874
5875
  const activeByDriver = /* @__PURE__ */ new Map();
5875
5876
  const watchAbort = new AbortController();
5877
+ const stoppedError = new OrchestrationError({
5878
+ code: "CANCELLED",
5879
+ message: "external orchestration controller stopped",
5880
+ retryable: false
5881
+ });
5882
+ let resolveStopped;
5883
+ const stoppedBoundary = new Promise((resolve) => {
5884
+ resolveStopped = resolve;
5885
+ });
5876
5886
  let stopped = false;
5887
+ let stopPromise;
5888
+ function throwIfStopped() {
5889
+ if (stopped) throw stoppedError;
5890
+ }
5891
+ async function whileRunning(operation) {
5892
+ throwIfStopped();
5893
+ const operationResult = Promise.resolve().then(operation).then(
5894
+ (value) => ({ kind: "value", value }),
5895
+ (error2) => ({
5896
+ kind: "error",
5897
+ error: error2 instanceof Error ? error2 : new Error(safeErrorMessageFromUnknown(error2))
5898
+ })
5899
+ );
5900
+ const result = await Promise.race([operationResult, stoppedBoundary]);
5901
+ if (result.kind === "stopped") throw stoppedError;
5902
+ if (result.kind === "error") throw result.error;
5903
+ return result.value;
5904
+ }
5905
+ function reportUnlessStopped(error2) {
5906
+ if (!stopped && error2 !== stoppedError) onError(error2);
5907
+ }
5908
+ async function drainWithDeadline(tasks) {
5909
+ let timeout;
5910
+ try {
5911
+ await Promise.race([
5912
+ Promise.allSettled(tasks).then(() => {
5913
+ }),
5914
+ new Promise((resolve) => {
5915
+ timeout = setTimeout(resolve, 1e3);
5916
+ })
5917
+ ]);
5918
+ } finally {
5919
+ if (timeout) clearTimeout(timeout);
5920
+ }
5921
+ }
5877
5922
  async function acquireDriverSlot(entry) {
5878
5923
  const limit = entry.capabilities.maxConcurrency;
5879
5924
  while (!stopped) {
@@ -5882,7 +5927,7 @@ function createExternalOrchestrationController(store, options) {
5882
5927
  activeByDriver.set(entry.name, current + 1);
5883
5928
  return true;
5884
5929
  }
5885
- await sleep(pollIntervalMs);
5930
+ await whileRunning(() => sleep(pollIntervalMs));
5886
5931
  }
5887
5932
  return false;
5888
5933
  }
@@ -5912,7 +5957,7 @@ function createExternalOrchestrationController(store, options) {
5912
5957
  }
5913
5958
  async function ensureRun(workload) {
5914
5959
  const reference = runReferenceOf(workload);
5915
- if (await store.get(reference)) return reference;
5960
+ if (await whileRunning(() => store.get(reference))) return reference;
5916
5961
  const manifest = createAgentRunManifest(reference.name, {
5917
5962
  workloadRef: {
5918
5963
  apiVersion: workload.apiVersion,
@@ -5924,7 +5969,7 @@ function createExternalOrchestrationController(store, options) {
5924
5969
  });
5925
5970
  manifest.metadata.namespace = workload.metadata.namespace;
5926
5971
  try {
5927
- await store.create(options.actor, manifest);
5972
+ await whileRunning(() => store.create(options.actor, manifest));
5928
5973
  } catch (error2) {
5929
5974
  if (!(error2 instanceof OrchestrationError) || error2.code !== "CONFLICT") throw error2;
5930
5975
  }
@@ -5932,12 +5977,14 @@ function createExternalOrchestrationController(store, options) {
5932
5977
  }
5933
5978
  async function updateStatus(reference, patch) {
5934
5979
  for (let attempt = 0; attempt < statusWriteAttempts; attempt += 1) {
5935
- const current = await store.get(reference);
5980
+ const current = await whileRunning(() => store.get(reference));
5936
5981
  if (!current) return;
5937
5982
  try {
5938
- await store.updateStatus(options.actor, reference, patch(current.status), {
5939
- resourceVersion: current.metadata.resourceVersion
5940
- });
5983
+ await whileRunning(
5984
+ () => store.updateStatus(options.actor, reference, patch(current.status), {
5985
+ resourceVersion: current.metadata.resourceVersion
5986
+ })
5987
+ );
5941
5988
  return;
5942
5989
  } catch (error2) {
5943
5990
  if (error2 instanceof OrchestrationError && error2.code === "CONFLICT") continue;
@@ -5977,6 +6024,7 @@ function createExternalOrchestrationController(store, options) {
5977
6024
  return entry;
5978
6025
  }
5979
6026
  async function fail(resource, error2) {
6027
+ throwIfStopped();
5980
6028
  const message = safeErrorMessageFromUnknown(error2, { fallback: "External orchestration failed" });
5981
6029
  if (resource.kind === AGENT_WORKLOAD_KIND) {
5982
6030
  await updateStatus(runReferenceOf(resource), () => ({
@@ -6049,6 +6097,7 @@ function createExternalOrchestrationController(store, options) {
6049
6097
  return terminal;
6050
6098
  }
6051
6099
  async function reconcileWorkload(resource) {
6100
+ throwIfStopped();
6052
6101
  const entry = findDriver(resource);
6053
6102
  const runtime = resolveExternalWorkloadRuntime(
6054
6103
  resource,
@@ -6057,7 +6106,7 @@ function createExternalOrchestrationController(store, options) {
6057
6106
  resolveExternalWorkloadResources(resource, runtime);
6058
6107
  const reference = referenceOf(resource);
6059
6108
  const runReference = await ensureRun(resource);
6060
- const latest = await store.get(reference);
6109
+ const latest = await whileRunning(() => store.get(reference));
6061
6110
  let externalId = latest?.status?.externalId ?? resource.status?.externalId;
6062
6111
  if (!externalId) {
6063
6112
  if (!options.authorizeWorkloadPlacement) {
@@ -6067,8 +6116,8 @@ function createExternalOrchestrationController(store, options) {
6067
6116
  retryable: false
6068
6117
  });
6069
6118
  }
6070
- const authorization = await options.authorizeWorkloadPlacement(resource, entry);
6071
- const health = await entry.driver.getHealth();
6119
+ const authorization = await whileRunning(() => options.authorizeWorkloadPlacement(resource, entry, watchAbort.signal));
6120
+ const health = await whileRunning(() => entry.driver.getHealth());
6072
6121
  if (!health.healthy) {
6073
6122
  throw new OrchestrationError({ code: "UNAVAILABLE", message: `external orchestrator '${entry.name}' is unhealthy`, retryable: true });
6074
6123
  }
@@ -6081,21 +6130,25 @@ function createExternalOrchestrationController(store, options) {
6081
6130
  placementPolicyDigest: authorization.policyDigest
6082
6131
  }));
6083
6132
  let scriptSource;
6084
- if (resource.spec.scriptReference) {
6085
- scriptSource = await options.resolveScriptSource?.(resource.spec.scriptReference);
6133
+ const scriptReference = resource.spec.scriptReference;
6134
+ if (scriptReference) {
6135
+ scriptSource = await whileRunning(async () => options.resolveScriptSource?.(scriptReference));
6086
6136
  if (scriptSource === void 0) {
6087
6137
  throw new OrchestrationError({
6088
6138
  code: "NOT_FOUND",
6089
- message: `script artifact '${resource.spec.scriptReference}' is unavailable for external placement`,
6139
+ message: `script artifact '${scriptReference}' is unavailable for external placement`,
6090
6140
  retryable: false
6091
6141
  });
6092
6142
  }
6093
6143
  }
6094
- const workerBootstrap = await options.createWorkerBootstrap?.(resource, runReference);
6095
- const placed = await entry.driver.placeWorkload(resource, options.actor, {
6096
- ...scriptSource !== void 0 ? { scriptSource } : {},
6097
- ...workerBootstrap !== void 0 ? { workerBootstrap } : {}
6098
- });
6144
+ const workerBootstrap = await whileRunning(async () => options.createWorkerBootstrap?.(resource, runReference));
6145
+ const placed = await whileRunning(
6146
+ () => entry.driver.placeWorkload(resource, options.actor, {
6147
+ ...scriptSource !== void 0 ? { scriptSource } : {},
6148
+ ...workerBootstrap !== void 0 ? { workerBootstrap } : {},
6149
+ signal: watchAbort.signal
6150
+ })
6151
+ );
6099
6152
  externalId = placed.externalId;
6100
6153
  await updateStatus(reference, (current) => ({
6101
6154
  ...current,
@@ -6109,12 +6162,13 @@ function createExternalOrchestrationController(store, options) {
6109
6162
  await updateStatus(runReference, () => ({ phase: "Running" }));
6110
6163
  }
6111
6164
  while (!stopped) {
6112
- const external = await entry.driver.getWorkloadStatus(externalId);
6165
+ const external = await whileRunning(() => entry.driver.getWorkloadStatus(externalId));
6113
6166
  if (await reflectWorkloadStatus(resource, external)) return;
6114
- await sleep(pollIntervalMs);
6167
+ await whileRunning(() => sleep(pollIntervalMs));
6115
6168
  }
6116
6169
  }
6117
6170
  async function reconcileToolOperation(resource) {
6171
+ throwIfStopped();
6118
6172
  const entry = findDriver(resource);
6119
6173
  const runtimeImage = resource.metadata.annotations?.["memeloop.io/runtime-image"];
6120
6174
  const contract = assertExternalToolOperationContract(
@@ -6123,10 +6177,10 @@ function createExternalOrchestrationController(store, options) {
6123
6177
  runtimeImage
6124
6178
  );
6125
6179
  const reference = referenceOf(resource);
6126
- const latest = await store.get(reference);
6180
+ const latest = await whileRunning(() => store.get(reference));
6127
6181
  let externalId = latest?.status?.externalId ?? resource.status?.externalId;
6128
6182
  if (!externalId) {
6129
- const health = await entry.driver.getHealth();
6183
+ const health = await whileRunning(() => entry.driver.getHealth());
6130
6184
  if (!health.healthy) {
6131
6185
  throw new OrchestrationError({ code: "UNAVAILABLE", message: `external orchestrator '${entry.name}' is unhealthy`, retryable: true });
6132
6186
  }
@@ -6142,14 +6196,14 @@ function createExternalOrchestrationController(store, options) {
6142
6196
  retryable: false
6143
6197
  });
6144
6198
  }
6145
- const authorization = await options.authorizeToolOperation(resource);
6199
+ const authorization = await whileRunning(() => options.authorizeToolOperation(resource, watchAbort.signal));
6146
6200
  if (authorization.approval) {
6147
6201
  await updateStatus(reference, (current) => ({
6148
6202
  ...current,
6149
6203
  approval: authorization.approval
6150
6204
  }));
6151
6205
  }
6152
- const placed = await entry.driver.executeToolOperation(resource, options.actor);
6206
+ const placed = await whileRunning(() => entry.driver.executeToolOperation(resource, options.actor));
6153
6207
  externalId = placed.externalId;
6154
6208
  await updateStatus(reference, (current) => ({
6155
6209
  ...current,
@@ -6162,27 +6216,28 @@ function createExternalOrchestrationController(store, options) {
6162
6216
  }));
6163
6217
  }
6164
6218
  while (!stopped) {
6165
- const external = await entry.driver.getToolOperationStatus(externalId);
6219
+ const external = await whileRunning(() => entry.driver.getToolOperationStatus(externalId));
6166
6220
  if (await reflectToolStatus(resource, external, contract)) return;
6167
- await sleep(pollIntervalMs);
6221
+ await whileRunning(() => sleep(pollIntervalMs));
6168
6222
  }
6169
6223
  }
6170
6224
  function maybeStart(resource) {
6225
+ if (stopped) return;
6171
6226
  const routed = resource;
6172
6227
  if (!routeOf(routed)) return;
6173
6228
  const phase = routed.status?.phase;
6174
6229
  if (phase === "Completed" || phase === "Failed" || phase === "Cancelled") return;
6175
6230
  if (active.has(routed.metadata.uid)) return;
6176
- active.add(routed.metadata.uid);
6177
- void (async () => {
6231
+ const task = (async () => {
6178
6232
  let slot;
6179
6233
  try {
6180
6234
  const entry = findDriver(routed);
6181
6235
  if (!await acquireDriverSlot(entry)) return;
6182
6236
  slot = entry.name;
6183
6237
  } catch (error2) {
6238
+ if (stopped || error2 === stoppedError) return;
6184
6239
  onError(error2);
6185
- await fail(routed, error2).catch(onError);
6240
+ await fail(routed, error2).catch(reportUnlessStopped);
6186
6241
  return;
6187
6242
  }
6188
6243
  try {
@@ -6195,18 +6250,25 @@ function createExternalOrchestrationController(store, options) {
6195
6250
  }
6196
6251
  return;
6197
6252
  } catch (error2) {
6253
+ if (stopped || error2 === stoppedError) return;
6198
6254
  onError(error2);
6199
6255
  if (!(error2 instanceof OrchestrationError) || !error2.retryable) {
6200
- await fail(routed, error2).catch(onError);
6256
+ await fail(routed, error2).catch(reportUnlessStopped);
6201
6257
  return;
6202
6258
  }
6203
- await sleep(pollIntervalMs);
6259
+ await whileRunning(() => sleep(pollIntervalMs));
6204
6260
  }
6205
6261
  }
6206
6262
  } finally {
6207
6263
  if (slot) releaseDriverSlot(slot);
6208
6264
  }
6209
- })().finally(() => active.delete(routed.metadata.uid));
6265
+ })();
6266
+ active.set(routed.metadata.uid, task);
6267
+ void task.finally(() => {
6268
+ if (active.get(routed.metadata.uid) === task) active.delete(routed.metadata.uid);
6269
+ }).catch((error2) => {
6270
+ if (!stopped && error2 !== stoppedError) onError(error2);
6271
+ });
6210
6272
  }
6211
6273
  async function cancelDeleted(resource) {
6212
6274
  const driverName = resource.status?.assignedDriver ?? routeOf(resource);
@@ -6227,7 +6289,7 @@ function createExternalOrchestrationController(store, options) {
6227
6289
  { apiVersion, kind },
6228
6290
  { signal: watchAbort.signal }
6229
6291
  )[Symbol.asyncIterator]();
6230
- const existing = await store.list({ apiVersion, kind });
6292
+ const existing = await whileRunning(() => store.list({ apiVersion, kind }));
6231
6293
  for (const resource of existing.items) maybeStart(resource);
6232
6294
  while (!stopped) {
6233
6295
  const next = await iterator.next();
@@ -6235,30 +6297,35 @@ function createExternalOrchestrationController(store, options) {
6235
6297
  const event = next.value;
6236
6298
  if (stopped) break;
6237
6299
  if (event.type === "DELETED") {
6238
- await cancelDeleted(event.resource).catch(onError);
6300
+ await cancelDeleted(event.resource).catch(reportUnlessStopped);
6239
6301
  } else if (event.type === "ADDED" || event.type === "MODIFIED") {
6240
6302
  maybeStart(event.resource);
6241
6303
  }
6242
6304
  }
6243
6305
  } catch (error2) {
6244
- onError(error2);
6306
+ if (!stopped && error2 !== stoppedError) onError(error2);
6307
+ }
6308
+ if (!stopped) {
6309
+ await whileRunning(() => sleep(1e3)).catch((error2) => {
6310
+ if (!stopped && error2 !== stoppedError) onError(error2);
6311
+ });
6245
6312
  }
6246
- if (!stopped) await sleep(1e3);
6247
6313
  }
6248
6314
  }
6249
6315
  const watchers = [
6250
6316
  runKind(AGENT_WORKLOAD_API_VERSION, AGENT_WORKLOAD_KIND),
6251
6317
  runKind(TOOL_OPERATION_API_VERSION, TOOL_OPERATION_KIND)
6252
6318
  ];
6253
- for (const watcher of watchers) void watcher.catch(onError);
6319
+ for (const watcher of watchers) void watcher.catch(reportUnlessStopped);
6254
6320
  return {
6255
6321
  async stop() {
6256
- stopped = true;
6257
- watchAbort.abort();
6258
- await Promise.race([
6259
- Promise.allSettled(watchers),
6260
- new Promise((resolve) => setTimeout(resolve, 50))
6261
- ]);
6322
+ if (!stopPromise) {
6323
+ stopped = true;
6324
+ resolveStopped({ kind: "stopped" });
6325
+ watchAbort.abort(stoppedError);
6326
+ stopPromise = drainWithDeadline([...watchers, ...active.values()]);
6327
+ }
6328
+ await stopPromise;
6262
6329
  }
6263
6330
  };
6264
6331
  }
@@ -9818,15 +9885,64 @@ function createWorkloadExecutionController(store, driver, options) {
9818
9885
  });
9819
9886
  }
9820
9887
  const active = /* @__PURE__ */ new Map();
9888
+ const executions = /* @__PURE__ */ new Map();
9889
+ const cancellationRequested = /* @__PURE__ */ new Set();
9890
+ const watchAbort = new AbortController();
9891
+ const stoppedError = new OrchestrationError({
9892
+ code: "CANCELLED",
9893
+ message: "workload execution controller stopped",
9894
+ retryable: false
9895
+ });
9896
+ let resolveStopped;
9897
+ const stoppedBoundary = new Promise((resolve) => {
9898
+ resolveStopped = resolve;
9899
+ });
9821
9900
  let stopped = false;
9901
+ let stopPromise;
9902
+ function throwIfStopped() {
9903
+ if (stopped) throw stoppedError;
9904
+ }
9905
+ async function whileRunning(operation) {
9906
+ throwIfStopped();
9907
+ const operationResult = Promise.resolve().then(operation).then(
9908
+ (value) => ({ kind: "value", value }),
9909
+ (error2) => ({
9910
+ kind: "error",
9911
+ error: error2 instanceof Error ? error2 : new Error(safeErrorMessageFromUnknown(error2))
9912
+ })
9913
+ );
9914
+ const result = await Promise.race([operationResult, stoppedBoundary]);
9915
+ if (result.kind === "stopped") throw stoppedError;
9916
+ if (result.kind === "error") throw result.error;
9917
+ return result.value;
9918
+ }
9919
+ function reportUnlessStopped(error2) {
9920
+ if (!stopped && error2 !== stoppedError) onError(error2);
9921
+ }
9922
+ async function drainWithDeadline(tasks) {
9923
+ let timeout;
9924
+ try {
9925
+ await Promise.race([
9926
+ Promise.allSettled(tasks).then(() => {
9927
+ }),
9928
+ new Promise((resolve) => {
9929
+ timeout = setTimeout(resolve, 1e3);
9930
+ })
9931
+ ]);
9932
+ } finally {
9933
+ if (timeout) clearTimeout(timeout);
9934
+ }
9935
+ }
9822
9936
  async function updateStatusWithRetry(reference, patch) {
9823
9937
  for (let attempt = 0; attempt < statusWriteAttempts; attempt += 1) {
9824
- const current = await store.get(reference);
9938
+ const current = await whileRunning(() => store.get(reference));
9825
9939
  if (!current) return;
9826
9940
  try {
9827
- await store.updateStatus(options.actor, reference, patch(current.status), {
9828
- resourceVersion: current.metadata.resourceVersion
9829
- });
9941
+ await whileRunning(
9942
+ () => store.updateStatus(options.actor, reference, patch(current.status), {
9943
+ resourceVersion: current.metadata.resourceVersion
9944
+ })
9945
+ );
9830
9946
  return;
9831
9947
  } catch (error2) {
9832
9948
  if (error2 instanceof OrchestrationError && error2.code === "CONFLICT") continue;
@@ -9861,22 +9977,26 @@ function createWorkloadExecutionController(store, driver, options) {
9861
9977
  }
9862
9978
  async function claimRuntimeExecution(reference) {
9863
9979
  for (let attempt = 0; attempt < statusWriteAttempts; attempt += 1) {
9864
- const current = await store.get(reference);
9980
+ const current = await whileRunning(
9981
+ () => store.get(reference)
9982
+ );
9865
9983
  if (!current) return null;
9866
9984
  if (current.status?.runtimeExecutionClaim) return null;
9867
9985
  try {
9868
- return await store.updateStatus(
9869
- options.actor,
9870
- reference,
9871
- {
9872
- ...current.status,
9873
- phase: "Starting",
9874
- runtimeExecutionClaim: {
9875
- controllerInstanceId,
9876
- claimedAt: (/* @__PURE__ */ new Date()).toISOString()
9877
- }
9878
- },
9879
- { resourceVersion: current.metadata.resourceVersion }
9986
+ return await whileRunning(
9987
+ () => store.updateStatus(
9988
+ options.actor,
9989
+ reference,
9990
+ {
9991
+ ...current.status,
9992
+ phase: "Starting",
9993
+ runtimeExecutionClaim: {
9994
+ controllerInstanceId,
9995
+ claimedAt: (/* @__PURE__ */ new Date()).toISOString()
9996
+ }
9997
+ },
9998
+ { resourceVersion: current.metadata.resourceVersion }
9999
+ )
9880
10000
  );
9881
10001
  } catch (error2) {
9882
10002
  if (error2 instanceof OrchestrationError && error2.code === "CONFLICT") {
@@ -9901,8 +10021,10 @@ function createWorkloadExecutionController(store, driver, options) {
9901
10021
  retryable: false
9902
10022
  });
9903
10023
  }
9904
- const current = await store.get(
9905
- runReference
10024
+ const current = await whileRunning(
10025
+ () => store.get(
10026
+ runReference
10027
+ )
9906
10028
  );
9907
10029
  if (!current) {
9908
10030
  throw new OrchestrationError({
@@ -9914,12 +10036,14 @@ function createWorkloadExecutionController(store, driver, options) {
9914
10036
  if (!workload.spec.modelPolicy?.modelClass) return { run: current };
9915
10037
  const binding = current.status?.assignedModelEndpoint;
9916
10038
  if (binding) {
9917
- const endpoint = await store.get({
9918
- apiVersion: binding.apiVersion || MODEL_ENDPOINT_API_VERSION,
9919
- kind: binding.kind || MODEL_ENDPOINT_KIND,
9920
- name: binding.name,
9921
- namespace: binding.namespace
9922
- });
10039
+ const endpoint = await whileRunning(
10040
+ () => store.get({
10041
+ apiVersion: binding.apiVersion || MODEL_ENDPOINT_API_VERSION,
10042
+ kind: binding.kind || MODEL_ENDPOINT_KIND,
10043
+ name: binding.name,
10044
+ namespace: binding.namespace
10045
+ })
10046
+ );
9923
10047
  if (endpoint && endpoint.metadata.uid === binding.uid && endpoint.status?.healthy === true && Number.isFinite(Date.parse(endpoint.status.heartbeat ?? "")) && Date.now() - Date.parse(endpoint.status.heartbeat ?? "") <= modelEndpointHeartbeatTtlMs && endpoint.spec.modelClassRef.name === workload.spec.modelPolicy.modelClass) {
9924
10048
  return { run: current, endpoint };
9925
10049
  }
@@ -9931,7 +10055,7 @@ function createWorkloadExecutionController(store, driver, options) {
9931
10055
  retryable: true
9932
10056
  });
9933
10057
  }
9934
- await sleep(dependencyPollIntervalMs);
10058
+ await whileRunning(() => sleep(dependencyPollIntervalMs));
9935
10059
  }
9936
10060
  }
9937
10061
  async function ensureNetworkAttachment(workload, runReference, runUid) {
@@ -9944,7 +10068,9 @@ function createWorkloadExecutionController(store, driver, options) {
9944
10068
  name: attachmentName,
9945
10069
  namespace: workload.metadata.namespace
9946
10070
  };
9947
- let attachment = await store.get(reference);
10071
+ let attachment = await whileRunning(
10072
+ () => store.get(reference)
10073
+ );
9948
10074
  if (!attachment) {
9949
10075
  const manifest = createNetworkAttachmentManifest(attachmentName, {
9950
10076
  networkClassRef: {
@@ -9968,7 +10094,7 @@ function createWorkloadExecutionController(store, driver, options) {
9968
10094
  nodeId: options.nodeId
9969
10095
  });
9970
10096
  manifest.metadata.namespace = workload.metadata.namespace;
9971
- attachment = await store.create(options.actor, manifest);
10097
+ attachment = await whileRunning(() => store.create(options.actor, manifest));
9972
10098
  }
9973
10099
  await updateStatusWithRetry(runReference, (current) => ({
9974
10100
  ...current,
@@ -9989,7 +10115,9 @@ function createWorkloadExecutionController(store, driver, options) {
9989
10115
  retryable: false
9990
10116
  });
9991
10117
  }
9992
- const current = await store.get(reference);
10118
+ const current = await whileRunning(
10119
+ () => store.get(reference)
10120
+ );
9993
10121
  if (!current || current.metadata.uid !== attachment.metadata.uid) {
9994
10122
  throw new OrchestrationError({
9995
10123
  code: "NOT_FOUND",
@@ -10005,7 +10133,9 @@ function createWorkloadExecutionController(store, driver, options) {
10005
10133
  });
10006
10134
  }
10007
10135
  if (current.status?.phase === "Attached" && current.status.handle) {
10008
- const networkClass = await store.get(current.spec.networkClassRef);
10136
+ const networkClass = await whileRunning(
10137
+ () => store.get(current.spec.networkClassRef)
10138
+ );
10009
10139
  if (networkClass && current.status.binding?.networkClassResourceVersion === networkClass.metadata.resourceVersion && current.status.assignedNode === options.nodeId && current.status.assignedDriver === networkClass.spec.driver) {
10010
10140
  return current;
10011
10141
  }
@@ -10017,14 +10147,16 @@ function createWorkloadExecutionController(store, driver, options) {
10017
10147
  retryable: true
10018
10148
  });
10019
10149
  }
10020
- await sleep(dependencyPollIntervalMs);
10150
+ await whileRunning(() => sleep(dependencyPollIntervalMs));
10021
10151
  }
10022
10152
  }
10023
10153
  async function waitForVolumeBindings(workload, runReference) {
10024
10154
  const expected = workload.spec.storagePolicy?.volumes ?? [];
10025
10155
  if (expected.length === 0) {
10026
- const run = await store.get(
10027
- runReference
10156
+ const run = await whileRunning(
10157
+ () => store.get(
10158
+ runReference
10159
+ )
10028
10160
  );
10029
10161
  return { run };
10030
10162
  }
@@ -10037,8 +10169,10 @@ function createWorkloadExecutionController(store, driver, options) {
10037
10169
  retryable: false
10038
10170
  });
10039
10171
  }
10040
- const run = await store.get(
10041
- runReference
10172
+ const run = await whileRunning(
10173
+ () => store.get(
10174
+ runReference
10175
+ )
10042
10176
  );
10043
10177
  if (!run) {
10044
10178
  throw new OrchestrationError({
@@ -10065,7 +10199,7 @@ function createWorkloadExecutionController(store, driver, options) {
10065
10199
  retryable: false
10066
10200
  });
10067
10201
  }
10068
- return { run, mounts: await options.resolveVolumeMounts(workload, run) };
10202
+ return { run, mounts: await whileRunning(() => options.resolveVolumeMounts(workload, run)) };
10069
10203
  }
10070
10204
  if (Date.now() >= deadline) {
10071
10205
  throw new OrchestrationError({
@@ -10074,12 +10208,14 @@ function createWorkloadExecutionController(store, driver, options) {
10074
10208
  retryable: true
10075
10209
  });
10076
10210
  }
10077
- await sleep(dependencyPollIntervalMs);
10211
+ await whileRunning(() => sleep(dependencyPollIntervalMs));
10078
10212
  }
10079
10213
  }
10080
10214
  async function requestDependencyRelease(runReference) {
10081
- const run = await store.get(
10082
- runReference
10215
+ const run = await whileRunning(
10216
+ () => store.get(
10217
+ runReference
10218
+ )
10083
10219
  );
10084
10220
  if (!run) return;
10085
10221
  const requestedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -10106,6 +10242,7 @@ function createWorkloadExecutionController(store, driver, options) {
10106
10242
  }
10107
10243
  }
10108
10244
  async function execute(workload) {
10245
+ throwIfStopped();
10109
10246
  const workloadReference_ = workloadReference(workload);
10110
10247
  const runName = `${workload.metadata.name}-run`;
10111
10248
  const runReference = {
@@ -10117,18 +10254,19 @@ function createWorkloadExecutionController(store, driver, options) {
10117
10254
  let runtimeClaimed = false;
10118
10255
  try {
10119
10256
  let scriptSource;
10120
- if (workload.spec.scriptReference) {
10121
- scriptSource = await options.resolveScriptSource?.(workload.spec.scriptReference);
10257
+ const scriptReference = workload.spec.scriptReference;
10258
+ if (scriptReference) {
10259
+ scriptSource = await whileRunning(async () => options.resolveScriptSource?.(scriptReference));
10122
10260
  if (!scriptSource) {
10123
10261
  await updateStatusWithRetry(workloadReference_, (current) => ({
10124
10262
  ...current,
10125
10263
  phase: "Failed",
10126
- lastRunResult: `script artifact '${workload.spec.scriptReference}' unavailable`
10264
+ lastRunResult: `script artifact '${scriptReference}' unavailable`
10127
10265
  }));
10128
10266
  return;
10129
10267
  }
10130
10268
  }
10131
- let run = await store.get(runReference);
10269
+ let run = await whileRunning(() => store.get(runReference));
10132
10270
  if (!run) {
10133
10271
  const manifest = createAgentRunManifest(runName, {
10134
10272
  workloadRef: {
@@ -10141,15 +10279,19 @@ function createWorkloadExecutionController(store, driver, options) {
10141
10279
  });
10142
10280
  manifest.metadata.namespace = workload.metadata.namespace;
10143
10281
  try {
10144
- run = await store.create(
10145
- options.actor,
10146
- manifest
10282
+ run = await whileRunning(
10283
+ () => store.create(
10284
+ options.actor,
10285
+ manifest
10286
+ )
10147
10287
  );
10148
10288
  } catch (error2) {
10149
10289
  if (!(error2 instanceof OrchestrationError) || error2.code !== "CONFLICT") {
10150
10290
  throw error2;
10151
10291
  }
10152
- run = await store.get(runReference);
10292
+ run = await whileRunning(
10293
+ () => store.get(runReference)
10294
+ );
10153
10295
  if (!run) throw error2;
10154
10296
  }
10155
10297
  }
@@ -10169,8 +10311,10 @@ function createWorkloadExecutionController(store, driver, options) {
10169
10311
  waitForVolumeBindings(workload, runReference)
10170
10312
  ]);
10171
10313
  run = volumeDependencies.run;
10172
- run = await store.get(
10173
- runReference
10314
+ run = await whileRunning(
10315
+ () => store.get(
10316
+ runReference
10317
+ )
10174
10318
  ) ?? run;
10175
10319
  await updateStatusWithRetry(workloadReference_, (current) => ({
10176
10320
  ...current,
@@ -10181,21 +10325,27 @@ function createWorkloadExecutionController(store, driver, options) {
10181
10325
  if (!claimedRun) return;
10182
10326
  runtimeClaimed = true;
10183
10327
  run = claimedRun;
10184
- const handle = await driver.start({
10185
- workload,
10186
- run,
10187
- ...dependencies.endpoint ? { modelEndpoint: dependencies.endpoint } : {},
10188
- ...networkAttachment ? { networkAttachment } : {},
10189
- ...volumeDependencies.mounts ? { volumeMounts: volumeDependencies.mounts } : {},
10190
- scriptSource,
10191
- message: options.messageForWorkload?.(workload) ?? workload.metadata.name
10192
- });
10328
+ const handle = await whileRunning(
10329
+ () => driver.start({
10330
+ workload,
10331
+ run,
10332
+ ...dependencies.endpoint ? { modelEndpoint: dependencies.endpoint } : {},
10333
+ ...networkAttachment ? { networkAttachment } : {},
10334
+ ...volumeDependencies.mounts ? { volumeMounts: volumeDependencies.mounts } : {},
10335
+ scriptSource,
10336
+ message: options.messageForWorkload?.(workload) ?? workload.metadata.name
10337
+ })
10338
+ );
10193
10339
  active.set(workload.metadata.uid, handle);
10340
+ if (cancellationRequested.has(workload.metadata.uid)) {
10341
+ await handle.cancel().catch(reportUnlessStopped);
10342
+ return;
10343
+ }
10194
10344
  await updateStatusWithRetry(runReference, (current) => ({
10195
10345
  ...current,
10196
10346
  phase: "Running"
10197
10347
  }));
10198
- const outcome = await handle.wait();
10348
+ const outcome = await whileRunning(() => handle.wait());
10199
10349
  await requestDependencyRelease(runReference);
10200
10350
  await updateStatusWithRetry(runReference, (current) => ({
10201
10351
  ...current,
@@ -10209,7 +10359,8 @@ function createWorkloadExecutionController(store, driver, options) {
10209
10359
  lastRunResult: outcome.summary ?? outcome.error?.message
10210
10360
  }));
10211
10361
  } catch (error2) {
10212
- await requestDependencyRelease(runReference).catch(onError);
10362
+ if (stopped || error2 === stoppedError) return;
10363
+ await requestDependencyRelease(runReference).catch(reportUnlessStopped);
10213
10364
  const cause = safeErrorMessageFromUnknown(error2, { fallback: "Runtime execution failed" });
10214
10365
  const message = runtimeClaimed ? `UNKNOWN_EFFECT: runtime execution failed after the durable pre-effect claim; verify external state before retrying: ${cause}` : cause;
10215
10366
  await updateStatusWithRetry(runReference, (current) => ({
@@ -10219,19 +10370,20 @@ function createWorkloadExecutionController(store, driver, options) {
10219
10370
  summary: message,
10220
10371
  exitCode: 1
10221
10372
  }
10222
- })).catch(onError);
10223
- if (stopped) return;
10373
+ })).catch(reportUnlessStopped);
10224
10374
  onError(error2);
10225
10375
  await updateStatusWithRetry(workloadReference_, (current) => ({
10226
10376
  ...current,
10227
10377
  phase: "Failed",
10228
10378
  lastRunResult: message
10229
- })).catch(onError);
10379
+ })).catch(reportUnlessStopped);
10230
10380
  } finally {
10231
10381
  active.delete(workload.metadata.uid);
10382
+ cancellationRequested.delete(workload.metadata.uid);
10232
10383
  }
10233
10384
  }
10234
10385
  async function recoverRunning(workload) {
10386
+ throwIfStopped();
10235
10387
  const runReference = {
10236
10388
  apiVersion: AGENT_RUN_API_VERSION,
10237
10389
  kind: AGENT_RUN_KIND,
@@ -10239,8 +10391,10 @@ function createWorkloadExecutionController(store, driver, options) {
10239
10391
  namespace: workload.metadata.namespace
10240
10392
  };
10241
10393
  try {
10242
- const run = await store.get(
10243
- runReference
10394
+ const run = await whileRunning(
10395
+ () => store.get(
10396
+ runReference
10397
+ )
10244
10398
  );
10245
10399
  if (run) {
10246
10400
  try {
@@ -10298,12 +10452,14 @@ function createWorkloadExecutionController(store, driver, options) {
10298
10452
  })
10299
10453
  );
10300
10454
  } catch (error2) {
10301
- onError(error2);
10455
+ if (!stopped && error2 !== stoppedError) onError(error2);
10302
10456
  } finally {
10303
10457
  active.delete(workload.metadata.uid);
10458
+ cancellationRequested.delete(workload.metadata.uid);
10304
10459
  }
10305
10460
  }
10306
10461
  function maybeStart(resource) {
10462
+ if (stopped) return;
10307
10463
  const workload = resource;
10308
10464
  const status = workload.status;
10309
10465
  if (!status || status.phase !== "Scheduling" && status.phase !== "Running") return;
@@ -10311,39 +10467,57 @@ function createWorkloadExecutionController(store, driver, options) {
10311
10467
  if (active.has(workload.metadata.uid)) return;
10312
10468
  active.set(workload.metadata.uid, { cancel: async () => {
10313
10469
  } });
10314
- if (status.phase === "Running") {
10315
- void recoverRunning(workload);
10316
- } else {
10317
- void execute(workload).catch(onError);
10318
- }
10470
+ const execution = status.phase === "Running" ? recoverRunning(workload) : execute(workload);
10471
+ executions.set(workload.metadata.uid, execution);
10472
+ void execution.finally(() => {
10473
+ if (executions.get(workload.metadata.uid) === execution) {
10474
+ executions.delete(workload.metadata.uid);
10475
+ }
10476
+ }).catch((error2) => {
10477
+ if (!stopped && error2 !== stoppedError) onError(error2);
10478
+ });
10319
10479
  }
10320
- void (async () => {
10480
+ const watcher = (async () => {
10321
10481
  while (!stopped) {
10322
10482
  try {
10323
10483
  for await (const event of store.watch(
10324
10484
  { apiVersion: AGENT_WORKLOAD_API_VERSION, kind: AGENT_WORKLOAD_KIND },
10325
- { sendInitialEvents: true }
10485
+ { sendInitialEvents: true, signal: watchAbort.signal }
10326
10486
  )) {
10327
10487
  if (stopped) break;
10328
10488
  if (event.type === "ADDED" || event.type === "MODIFIED") {
10329
10489
  maybeStart(event.resource);
10330
10490
  } else if (event.type === "DELETED") {
10331
10491
  const workload = event.resource;
10332
- await active.get(workload.metadata.uid)?.cancel().catch(onError);
10492
+ cancellationRequested.add(workload.metadata.uid);
10493
+ await active.get(workload.metadata.uid)?.cancel().catch(reportUnlessStopped);
10333
10494
  }
10334
10495
  }
10335
10496
  } catch (error2) {
10336
- onError(error2);
10497
+ if (!stopped && error2 !== stoppedError) onError(error2);
10498
+ }
10499
+ if (!stopped) {
10500
+ await whileRunning(() => sleep(1e3)).catch((error2) => {
10501
+ if (!stopped && error2 !== stoppedError) onError(error2);
10502
+ });
10337
10503
  }
10338
- if (!stopped) await sleep(1e3);
10339
10504
  }
10340
- })().catch(onError);
10505
+ })();
10506
+ void watcher.catch((error2) => {
10507
+ if (!stopped && error2 !== stoppedError) onError(error2);
10508
+ });
10341
10509
  return {
10342
10510
  async stop() {
10343
- stopped = true;
10344
- for (const handle of active.values()) {
10345
- await handle.cancel().catch(() => void 0);
10511
+ if (!stopPromise) {
10512
+ stopped = true;
10513
+ resolveStopped({ kind: "stopped" });
10514
+ watchAbort.abort(stoppedError);
10515
+ const cancellations = [...active.values()].map(async (handle) => {
10516
+ await handle.cancel().catch(() => void 0);
10517
+ });
10518
+ stopPromise = drainWithDeadline([...cancellations, watcher, ...executions.values()]);
10346
10519
  }
10520
+ await stopPromise;
10347
10521
  }
10348
10522
  };
10349
10523
  }
@@ -12095,6 +12269,7 @@ export {
12095
12269
  DEVICE_HEARTBEAT_DEFAULT_MAX_CLOCK_SKEW_MS,
12096
12270
  DEVICE_HEARTBEAT_LIMITS,
12097
12271
  DEVICE_HEARTBEAT_SIGNATURE_DOMAIN,
12272
+ DEVICE_ORCHESTRATION_FRAME_LIMITS,
12098
12273
  DEVICE_ORCHESTRATION_PROTOCOL,
12099
12274
  DEVICE_PAIRING_INVITE_MAX_CLOCK_SKEW_MS,
12100
12275
  DEVICE_PAIRING_INVITE_PROTOCOL,