rivetkit 2.3.0-rc.5 → 2.3.0-rc.7

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 (142) hide show
  1. package/dist/browser/client.d.ts +35 -3
  2. package/dist/browser/client.js +795 -200
  3. package/dist/browser/client.js.map +1 -1
  4. package/dist/browser/inspector/client.js +4 -3
  5. package/dist/browser/inspector/client.js.map +1 -1
  6. package/dist/tsup/actor/errors.cjs +4 -2
  7. package/dist/tsup/actor/errors.cjs.map +1 -1
  8. package/dist/tsup/actor/errors.d.cts +1 -74
  9. package/dist/tsup/actor/errors.d.ts +1 -74
  10. package/dist/tsup/actor/errors.js +3 -1
  11. package/dist/tsup/agent-os/index.cjs +7 -5
  12. package/dist/tsup/agent-os/index.cjs.map +1 -1
  13. package/dist/tsup/agent-os/index.d.cts +35 -3
  14. package/dist/tsup/agent-os/index.d.ts +35 -3
  15. package/dist/tsup/agent-os/index.js +7 -5
  16. package/dist/tsup/agent-os/index.js.map +1 -1
  17. package/dist/tsup/{chunk-2GANBXVP.cjs → chunk-2H4ISA4Y.cjs} +10 -10
  18. package/dist/tsup/chunk-2H4ISA4Y.cjs.map +1 -0
  19. package/dist/tsup/{chunk-UXTP4EBU.js → chunk-4DJMFOSU.js} +2 -2
  20. package/dist/tsup/{chunk-LDTT6WKJ.js → chunk-4LTY5TOO.js} +132 -4
  21. package/dist/tsup/chunk-4LTY5TOO.js.map +1 -0
  22. package/dist/tsup/{chunk-PGYEMIOE.js → chunk-52TPEKEC.js} +2 -2
  23. package/dist/tsup/{chunk-OVJX4IFY.cjs → chunk-55E7IR6D.cjs} +4 -4
  24. package/dist/tsup/{chunk-OVJX4IFY.cjs.map → chunk-55E7IR6D.cjs.map} +1 -1
  25. package/dist/tsup/{chunk-V3QNBJ7N.cjs → chunk-63WNTDRC.cjs} +31 -10
  26. package/dist/tsup/chunk-63WNTDRC.cjs.map +1 -0
  27. package/dist/tsup/{chunk-SULB574D.js → chunk-CMV6N5OX.js} +3 -3
  28. package/dist/tsup/{chunk-T6YVRM4K.js → chunk-D5G75T7J.js} +3 -1
  29. package/dist/tsup/chunk-D5G75T7J.js.map +1 -0
  30. package/dist/tsup/{chunk-NW2J4SOL.cjs → chunk-FEOG44WH.cjs} +137 -9
  31. package/dist/tsup/chunk-FEOG44WH.cjs.map +1 -0
  32. package/dist/tsup/{chunk-HR547GVH.cjs → chunk-G5HUSWP4.cjs} +8 -8
  33. package/dist/tsup/{chunk-HR547GVH.cjs.map → chunk-G5HUSWP4.cjs.map} +1 -1
  34. package/dist/tsup/{chunk-N2DQSJIW.js → chunk-HERL2VQ2.js} +17 -48
  35. package/dist/tsup/chunk-HERL2VQ2.js.map +1 -0
  36. package/dist/tsup/{chunk-LELRJK66.cjs → chunk-SJLPZEA3.cjs} +3 -3
  37. package/dist/tsup/{chunk-LELRJK66.cjs.map → chunk-SJLPZEA3.cjs.map} +1 -1
  38. package/dist/tsup/{chunk-WQ4HNA4W.cjs → chunk-SRNOPUC6.cjs} +4 -2
  39. package/dist/tsup/chunk-SRNOPUC6.cjs.map +1 -0
  40. package/dist/tsup/{chunk-K34B3OVG.js → chunk-TMLOKTRB.js} +30 -9
  41. package/dist/tsup/chunk-TMLOKTRB.js.map +1 -0
  42. package/dist/tsup/{chunk-NATOT3ET.js → chunk-VFIY6GWO.js} +4 -4
  43. package/dist/tsup/chunk-VFIY6GWO.js.map +1 -0
  44. package/dist/tsup/{chunk-JY73X7VU.js → chunk-VJ4Y4WBT.js} +692 -114
  45. package/dist/tsup/chunk-VJ4Y4WBT.js.map +1 -0
  46. package/dist/tsup/{chunk-JRCZDHXT.cjs → chunk-X6HIFXNK.cjs} +23 -54
  47. package/dist/tsup/chunk-X6HIFXNK.cjs.map +1 -0
  48. package/dist/tsup/{chunk-FTZIZ3JG.cjs → chunk-ZGPX6KAH.cjs} +838 -260
  49. package/dist/tsup/chunk-ZGPX6KAH.cjs.map +1 -0
  50. package/dist/tsup/client/mod.cjs +7 -7
  51. package/dist/tsup/client/mod.d.cts +3 -4
  52. package/dist/tsup/client/mod.d.ts +3 -4
  53. package/dist/tsup/client/mod.js +6 -6
  54. package/dist/tsup/common/log.cjs +3 -3
  55. package/dist/tsup/common/log.js +2 -2
  56. package/dist/tsup/common/websocket.cjs +4 -4
  57. package/dist/tsup/common/websocket.js +3 -3
  58. package/dist/tsup/{config-CvQUtDp9.d.ts → config-Ak1lv4gF.d.ts} +27 -5
  59. package/dist/tsup/{config-C-a9vrke.d.cts → config-DU_xj4qZ.d.cts} +27 -5
  60. package/dist/tsup/{context-A7R0bsZL.d.ts → context-DAAp4Lpg.d.ts} +1 -1
  61. package/dist/tsup/{context-CA3r-pf2.d.cts → context-Dt_L55q8.d.cts} +1 -1
  62. package/dist/tsup/inspector/mod.cjs +6 -6
  63. package/dist/tsup/inspector/mod.js +5 -5
  64. package/dist/tsup/mod.cjs +507 -308
  65. package/dist/tsup/mod.cjs.map +1 -1
  66. package/dist/tsup/mod.d.cts +4 -5
  67. package/dist/tsup/mod.d.ts +4 -5
  68. package/dist/tsup/mod.js +432 -233
  69. package/dist/tsup/mod.js.map +1 -1
  70. package/dist/tsup/process-metrics-NW754INA.js +118 -0
  71. package/dist/tsup/process-metrics-NW754INA.js.map +1 -0
  72. package/dist/tsup/process-metrics-TYAGKCEJ.cjs +118 -0
  73. package/dist/tsup/process-metrics-TYAGKCEJ.cjs.map +1 -0
  74. package/dist/tsup/test/mod.cjs +10 -10
  75. package/dist/tsup/test/mod.d.cts +2 -3
  76. package/dist/tsup/test/mod.d.ts +2 -3
  77. package/dist/tsup/test/mod.js +6 -6
  78. package/dist/tsup/utils-DVekpm4I.d.cts +103 -0
  79. package/dist/tsup/utils-DVekpm4I.d.ts +103 -0
  80. package/dist/tsup/utils.cjs +3 -3
  81. package/dist/tsup/utils.d.cts +1 -1
  82. package/dist/tsup/utils.d.ts +1 -1
  83. package/dist/tsup/utils.js +2 -2
  84. package/dist/tsup/workflow/mod.cjs +41 -16
  85. package/dist/tsup/workflow/mod.cjs.map +1 -1
  86. package/dist/tsup/workflow/mod.d.cts +4 -5
  87. package/dist/tsup/workflow/mod.d.ts +4 -5
  88. package/dist/tsup/workflow/mod.js +35 -10
  89. package/dist/tsup/workflow/mod.js.map +1 -1
  90. package/package.json +11 -10
  91. package/src/actor/config.ts +3 -0
  92. package/src/actor/errors.ts +53 -7
  93. package/src/agent-os/actor/session.ts +2 -2
  94. package/src/client/actor-conn.ts +55 -60
  95. package/src/client/actor-handle.ts +59 -24
  96. package/src/client/errors.ts +2 -1
  97. package/src/client/queue.ts +2 -1
  98. package/src/client/raw-utils.ts +2 -4
  99. package/src/client/utils.ts +32 -4
  100. package/src/common/actor-router-consts.ts +4 -0
  101. package/src/common/bare/generated/client-protocol/v4.ts +599 -0
  102. package/src/common/client-protocol-versioned.ts +125 -18
  103. package/src/common/client-protocol-zod.ts +7 -0
  104. package/src/common/client-protocol.ts +1 -1
  105. package/src/common/database/native-database.test.ts +35 -0
  106. package/src/common/database/native-database.ts +8 -4
  107. package/src/common/encoding.ts +243 -5
  108. package/src/common/inline-websocket-adapter.ts +12 -12
  109. package/src/common/log.ts +1 -0
  110. package/src/common/router.ts +40 -10
  111. package/src/common/utils.ts +9 -200
  112. package/src/drivers/engine/actor-driver.ts +29 -28
  113. package/src/engine-client/actor-websocket-client.ts +2 -1
  114. package/src/engine-client/mod.ts +3 -2
  115. package/src/registry/config/index.ts +3 -5
  116. package/src/registry/index.ts +90 -16
  117. package/src/registry/napi-runtime.ts +15 -0
  118. package/src/registry/native.ts +197 -255
  119. package/src/registry/process-metrics.ts +183 -0
  120. package/src/registry/runtime.ts +4 -0
  121. package/src/registry/wasm-runtime.ts +9 -0
  122. package/src/registry/write-through-proxy.ts +40 -0
  123. package/src/serde.ts +2 -2
  124. package/src/workflow/context.ts +32 -5
  125. package/src/workflow/inspector.ts +2 -1
  126. package/dist/tsup/chunk-2GANBXVP.cjs.map +0 -1
  127. package/dist/tsup/chunk-FTZIZ3JG.cjs.map +0 -1
  128. package/dist/tsup/chunk-JRCZDHXT.cjs.map +0 -1
  129. package/dist/tsup/chunk-JY73X7VU.js.map +0 -1
  130. package/dist/tsup/chunk-K34B3OVG.js.map +0 -1
  131. package/dist/tsup/chunk-LDTT6WKJ.js.map +0 -1
  132. package/dist/tsup/chunk-N2DQSJIW.js.map +0 -1
  133. package/dist/tsup/chunk-NATOT3ET.js.map +0 -1
  134. package/dist/tsup/chunk-NW2J4SOL.cjs.map +0 -1
  135. package/dist/tsup/chunk-T6YVRM4K.js.map +0 -1
  136. package/dist/tsup/chunk-V3QNBJ7N.cjs.map +0 -1
  137. package/dist/tsup/chunk-WQ4HNA4W.cjs.map +0 -1
  138. package/dist/tsup/utils-fwx3o3K9.d.cts +0 -18
  139. package/dist/tsup/utils-fwx3o3K9.d.ts +0 -18
  140. /package/dist/tsup/{chunk-UXTP4EBU.js.map → chunk-4DJMFOSU.js.map} +0 -0
  141. /package/dist/tsup/{chunk-PGYEMIOE.js.map → chunk-52TPEKEC.js.map} +0 -0
  142. /package/dist/tsup/{chunk-SULB574D.js.map → chunk-CMV6N5OX.js.map} +0 -0
@@ -22,6 +22,7 @@ import {
22
22
  import { assertUnreachable, stringifyError } from "@/common/utils";
23
23
  import type { UniversalWebSocket } from "@/common/websocket-interface";
24
24
  import type { EngineControlClient } from "@/engine-client/driver";
25
+ import type { JsonCompatValue } from "@/common/encoding";
25
26
  import {
26
27
  decodeCborCompat,
27
28
  deserializeWithEncoding,
@@ -56,7 +57,6 @@ import {
56
57
  type QueueSendResult,
57
58
  type QueueSendWaitOptions,
58
59
  } from "./queue";
59
- import { resolveGatewayTarget } from "./resolve-gateway-target";
60
60
  import {
61
61
  type WebSocketMessage as ConnMessage,
62
62
  messageLength,
@@ -94,8 +94,6 @@ interface EventSubscriptions<Args extends Array<unknown>> {
94
94
  once: boolean;
95
95
  }
96
96
 
97
- const DEFAULT_MAX_INCOMING_MESSAGE_SIZE = 65_536;
98
-
99
97
  /**
100
98
  * A function that unsubscribes from an event.
101
99
  *
@@ -237,7 +235,9 @@ export class ActorConnRaw {
237
235
  },
238
236
  });
239
237
 
240
- this.#keepNodeAliveInterval = setInterval(() => 60_000);
238
+ // Keep the Node event loop alive while this connection is active without blocking exit.
239
+ this.#keepNodeAliveInterval = setInterval(() => {}, 60_000);
240
+ this.#keepNodeAliveInterval.unref?.();
241
241
  }
242
242
 
243
243
  #clearResolvedActorIdentity() {
@@ -578,9 +578,7 @@ export class ActorConnRaw {
578
578
 
579
579
  async #connectWebSocket() {
580
580
  const params = await this.#resolveConnectionParams();
581
- const target = this.#gatewayOptions.skipReadyWait
582
- ? await this.#resolveGatewayTargetForSkipReadyWait()
583
- : getGatewayTarget(this.#actorResolutionState);
581
+ const target = getGatewayTarget(this.#actorResolutionState);
584
582
  const ws = await this.#driver.openWebSocket(
585
583
  PATH_CONNECT,
586
584
  target,
@@ -634,25 +632,6 @@ export class ActorConnRaw {
634
632
  });
635
633
  }
636
634
 
637
- async #resolveGatewayTargetForSkipReadyWait() {
638
- if ("getForId" in this.#actorResolutionState) {
639
- return {
640
- directId: this.#actorResolutionState.getForId.actorId,
641
- } as const;
642
- }
643
-
644
- if (this.#actorId) {
645
- return { directId: this.#actorId } as const;
646
- }
647
-
648
- return {
649
- directId: await resolveGatewayTarget(
650
- this.#driver,
651
- this.#actorResolutionState,
652
- ),
653
- } as const;
654
- }
655
-
656
635
  /** Called by the onopen event from drivers. */
657
636
  #handleOnOpen() {
658
637
  // Connection was disposed before Init message arrived - close the websocket to avoid leak
@@ -754,7 +733,7 @@ export class ActorConnRaw {
754
733
  this.#handleOnOpen();
755
734
  } else if (response.body.tag === "Error") {
756
735
  // Connection error
757
- const { group, code, message, metadata, actionId } =
736
+ const { group, code, message, metadata, actionId, actor } =
758
737
  response.body.val;
759
738
 
760
739
  if (actionId !== null) {
@@ -769,10 +748,16 @@ export class ActorConnRaw {
769
748
  code,
770
749
  message,
771
750
  metadata,
751
+ actorId: actor?.actorId,
752
+ generation: actor?.generation,
753
+ actorKey: actor?.key,
772
754
  });
773
755
 
774
756
  inFlight.reject(
775
- new errors.ActorError(group, code, message, metadata),
757
+ new errors.ActorError(group, code, message, {
758
+ metadata,
759
+ actor,
760
+ }),
776
761
  );
777
762
  } else {
778
763
  logger().warn({
@@ -781,12 +766,18 @@ export class ActorConnRaw {
781
766
  code,
782
767
  message,
783
768
  metadata,
769
+ actorId: actor?.actorId,
770
+ generation: actor?.generation,
771
+ actorKey: actor?.key,
784
772
  });
785
773
 
786
774
  if (this.#shouldReconnectForStaleActor(group, code)) {
787
775
  this.#clearResolvedActorIdentity();
788
776
  this.#onOpenPromise?.reject(
789
- new errors.ActorError(group, code, message, metadata),
777
+ new errors.ActorError(group, code, message, {
778
+ metadata,
779
+ actor,
780
+ }),
790
781
  );
791
782
  return;
792
783
  }
@@ -796,7 +787,7 @@ export class ActorConnRaw {
796
787
  group,
797
788
  code,
798
789
  message,
799
- metadata,
790
+ { metadata, actor },
800
791
  );
801
792
  if (errors.isSchedulingError(group, code) && this.#actorId) {
802
793
  const schedulingError = await checkForSchedulingError(
@@ -1279,7 +1270,7 @@ export class ActorConnRaw {
1279
1270
  name: msg.body.val.name,
1280
1271
  args: bufferToArrayBuffer(
1281
1272
  encodeCborCompat(
1282
- msg.body.val.args,
1273
+ msg.body.val.args as JsonCompatValue,
1283
1274
  ),
1284
1275
  ),
1285
1276
  },
@@ -1290,34 +1281,8 @@ export class ActorConnRaw {
1290
1281
  }
1291
1282
  },
1292
1283
  );
1293
- const serializedLength = messageLength(messageSerialized);
1294
- if (
1295
- serializedLength > DEFAULT_MAX_INCOMING_MESSAGE_SIZE &&
1296
- message.body.tag === "ActionRequest"
1297
- ) {
1298
- const actionId = Number(message.body.val.id);
1299
- const inFlight = this.#takeActionInFlight(actionId);
1300
- const error = new errors.ActorError(
1301
- "message",
1302
- "incoming_too_long",
1303
- "Incoming message too long",
1304
- {
1305
- maxSize: DEFAULT_MAX_INCOMING_MESSAGE_SIZE,
1306
- actualSize: serializedLength,
1307
- },
1308
- );
1309
- logger().warn({
1310
- msg: "rejecting oversized connection action request",
1311
- actionId,
1312
- actionName: inFlight.name,
1313
- actualSize: serializedLength,
1314
- maxSize: DEFAULT_MAX_INCOMING_MESSAGE_SIZE,
1315
- });
1316
- inFlight.reject(error);
1317
- this.#dispatchActorError(error);
1318
- return;
1319
- }
1320
1284
  this.#websocket.send(messageSerialized);
1285
+ const serializedLength = messageLength(messageSerialized);
1321
1286
  logger().trace({
1322
1287
  msg: "sent websocket message",
1323
1288
  len: serializedLength,
@@ -1368,6 +1333,7 @@ export class ActorConnRaw {
1368
1333
  message: string;
1369
1334
  metadata: unknown;
1370
1335
  actionId: bigint | null;
1336
+ actor?: errors.ActorSpecifier;
1371
1337
  };
1372
1338
  }
1373
1339
  | { tag: "ActionResponse"; val: { id: bigint; output: unknown } }
@@ -1382,8 +1348,26 @@ export class ActorConnRaw {
1382
1348
  buffer,
1383
1349
  CLIENT_PROTOCOL_TO_CLIENT,
1384
1350
  ToClientSchema,
1385
- // JSON: values are already the correct type
1386
- (msg): ToClientJson => msg as ToClientJson,
1351
+ // JSON/CBOR: normalize actor generation to the public number shape.
1352
+ (msg): any => {
1353
+ if (msg.body.tag !== "Error" || !msg.body.val.actor) {
1354
+ return msg as ToClientJson;
1355
+ }
1356
+ return {
1357
+ body: {
1358
+ tag: "Error",
1359
+ val: {
1360
+ ...msg.body.val,
1361
+ actor: {
1362
+ ...msg.body.val.actor,
1363
+ generation: Number(
1364
+ msg.body.val.actor.generation,
1365
+ ),
1366
+ },
1367
+ },
1368
+ },
1369
+ };
1370
+ },
1387
1371
  // BARE: need to decode ArrayBuffer fields back to unknown
1388
1372
  (msg): any => {
1389
1373
  if (msg.body.tag === "Error") {
@@ -1402,6 +1386,17 @@ export class ActorConnRaw {
1402
1386
  )
1403
1387
  : null,
1404
1388
  actionId: msg.body.val.actionId,
1389
+ actor: msg.body.val.actor
1390
+ ? {
1391
+ actorId: msg.body.val.actor.actorId,
1392
+ generation: Number(
1393
+ msg.body.val.actor.generation,
1394
+ ),
1395
+ key:
1396
+ msg.body.val.actor.key ??
1397
+ undefined,
1398
+ }
1399
+ : undefined,
1405
1400
  },
1406
1401
  },
1407
1402
  };
@@ -1,4 +1,5 @@
1
1
  import type { AnyActorDefinition } from "@/actor/definition";
2
+ import type { ActorSpecifier } from "@/actor/errors";
2
3
  import type { Encoding } from "@/common/encoding";
3
4
  import {
4
5
  HEADER_CONN_PARAMS,
@@ -22,6 +23,7 @@ import {
22
23
  } from "@/common/client-protocol-zod";
23
24
  import { deconstructError } from "@/common/utils";
24
25
  import type { EngineControlClient } from "@/engine-client/driver";
26
+ import type { JsonCompatValue } from "@/common/encoding";
25
27
  import { decodeCborCompat, deserializeWithEncoding, encodeCborCompat } from "@/serde";
26
28
  import { bufferToArrayBuffer } from "@/utils";
27
29
  import type {
@@ -139,7 +141,13 @@ export class ActorHandleRaw {
139
141
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
140
142
  let actorId: string | undefined;
141
143
  try {
142
- const target = await this.#resolveActionTarget(useQueryTarget);
144
+ const gatewayOptions = resolveActorGatewayOptions(
145
+ this.#gatewayOptions,
146
+ );
147
+ const target = await this.#resolveGatewayRequestTarget(
148
+ useQueryTarget,
149
+ gatewayOptions,
150
+ );
143
151
  actorId = "directId" in target ? target.directId : undefined;
144
152
 
145
153
  return await createQueueSender({
@@ -149,17 +157,13 @@ export class ActorHandleRaw {
149
157
  return await this.#driver.sendRequest(
150
158
  target,
151
159
  request,
152
- resolveActorGatewayOptions(
153
- this.#gatewayOptions,
154
- ),
160
+ gatewayOptions,
155
161
  );
156
162
  },
157
163
  }).send(name, body, options as any);
158
164
  } catch (err) {
159
- const { group, code, message, metadata } = deconstructError(
165
+ const { group, code, message, metadata, actor } = deconstructError(
160
166
  err,
161
- logger(),
162
- {},
163
167
  true,
164
168
  );
165
169
 
@@ -216,7 +220,7 @@ export class ActorHandleRaw {
216
220
  continue;
217
221
  }
218
222
 
219
- throw new ActorError(group, code, message, metadata);
223
+ throw new ActorError(group, code, message, { metadata, actor });
220
224
  }
221
225
  }
222
226
 
@@ -270,7 +274,10 @@ export class ActorHandleRaw {
270
274
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
271
275
  let actorId: string | undefined;
272
276
  try {
273
- const target = await this.#resolveActionTarget(useQueryTarget);
277
+ const target = await this.#resolveGatewayRequestTarget(
278
+ useQueryTarget,
279
+ gatewayOptions,
280
+ );
274
281
  actorId = "directId" in target ? target.directId : undefined;
275
282
 
276
283
  logger().debug(
@@ -326,7 +333,7 @@ export class ActorHandleRaw {
326
333
  args,
327
334
  }),
328
335
  requestToBare: (args): protocol.HttpActionRequest => ({
329
- args: bufferToArrayBuffer(encodeCborCompat(args)),
336
+ args: bufferToArrayBuffer(encodeCborCompat(args as JsonCompatValue)),
330
337
  }),
331
338
  responseFromJson: (json): Response => json.output as Response,
332
339
  responseFromBare: (bare): Response =>
@@ -337,10 +344,8 @@ export class ActorHandleRaw {
337
344
  }
338
345
  return output;
339
346
  } catch (err) {
340
- const { group, code, message, metadata } = deconstructError(
347
+ const { group, code, message, metadata, actor } = deconstructError(
341
348
  err,
342
- logger(),
343
- {},
344
349
  true,
345
350
  );
346
351
 
@@ -382,7 +387,7 @@ export class ActorHandleRaw {
382
387
  "actor",
383
388
  "not_found",
384
389
  "The actor does not exist or was destroyed.",
385
- metadata,
390
+ { metadata, actor },
386
391
  );
387
392
  }
388
393
 
@@ -398,7 +403,7 @@ export class ActorHandleRaw {
398
403
  continue;
399
404
  }
400
405
 
401
- throw new ActorError(group, code, message, metadata);
406
+ throw new ActorError(group, code, message, { metadata, actor });
402
407
  }
403
408
  }
404
409
 
@@ -561,6 +566,17 @@ export class ActorHandleRaw {
561
566
  }
562
567
  }
563
568
 
569
+ async #resolveGatewayRequestTarget(
570
+ useQueryTarget: boolean,
571
+ gatewayOptions: ActorGatewayOptions,
572
+ ) {
573
+ if (gatewayOptions.skipReadyWait) {
574
+ return getGatewayTarget(this.#actorResolutionState);
575
+ }
576
+
577
+ return await this.#resolveActionTarget(useQueryTarget);
578
+ }
579
+
564
580
  /**
565
581
  * Establishes a persistent connection to the actor.
566
582
  *
@@ -619,7 +635,10 @@ export class ActorHandleRaw {
619
635
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
620
636
  let actorId: string | undefined;
621
637
  try {
622
- const target = await this.#resolveActionTarget(useQueryTarget);
638
+ const target = await this.#resolveGatewayRequestTarget(
639
+ useQueryTarget,
640
+ gatewayOptions,
641
+ );
623
642
  actorId = "directId" in target ? target.directId : undefined;
624
643
  const response = await rawHttpFetch(
625
644
  this.#driver,
@@ -644,10 +663,8 @@ export class ActorHandleRaw {
644
663
  }
645
664
  return response;
646
665
  } catch (err) {
647
- const { group, code, message, metadata } = deconstructError(
666
+ const { group, code, message, metadata, actor } = deconstructError(
648
667
  err,
649
- logger(),
650
- {},
651
668
  true,
652
669
  );
653
670
 
@@ -691,7 +708,7 @@ export class ActorHandleRaw {
691
708
  continue;
692
709
  }
693
710
 
694
- throw new ActorError(group, code, message, metadata);
711
+ throw new ActorError(group, code, message, { metadata, actor });
695
712
  }
696
713
  }
697
714
 
@@ -771,6 +788,7 @@ export class ActorHandleRaw {
771
788
  code: string;
772
789
  message: string;
773
790
  metadata?: unknown;
791
+ actor?: ActorSpecifier;
774
792
  } | null> {
775
793
  if (response.ok) {
776
794
  return null;
@@ -790,13 +808,22 @@ export class ActorHandleRaw {
790
808
  code: string;
791
809
  message: string;
792
810
  metadata?: unknown;
811
+ actor?: ActorSpecifier;
793
812
  }
794
813
  >(
795
814
  encoding,
796
815
  new Uint8Array(await response.clone().arrayBuffer()),
797
816
  HTTP_RESPONSE_ERROR_VERSIONED,
798
817
  HttpResponseErrorSchema,
799
- (json) => json as HttpResponseErrorJson,
818
+ (json) => ({
819
+ ...json,
820
+ actor: json.actor
821
+ ? {
822
+ ...json.actor,
823
+ generation: Number(json.actor.generation),
824
+ }
825
+ : undefined,
826
+ }),
800
827
  (bare) => ({
801
828
  group: bare.group,
802
829
  code: bare.code,
@@ -804,6 +831,13 @@ export class ActorHandleRaw {
804
831
  metadata: bare.metadata
805
832
  ? decodeCborCompat(new Uint8Array(bare.metadata))
806
833
  : undefined,
834
+ actor: bare.actor
835
+ ? {
836
+ actorId: bare.actor.actorId,
837
+ generation: Number(bare.actor.generation),
838
+ key: bare.actor.key ?? undefined,
839
+ }
840
+ : undefined,
807
841
  }),
808
842
  );
809
843
  } catch {
@@ -824,9 +858,10 @@ export class ActorHandleRaw {
824
858
  this.#gatewayOptions,
825
859
  options,
826
860
  );
827
- const target = gatewayOptions.skipReadyWait
828
- ? await this.#resolveActionTarget(false)
829
- : getGatewayTarget(this.#actorResolutionState);
861
+ const target = await this.#resolveGatewayRequestTarget(
862
+ false,
863
+ gatewayOptions,
864
+ );
830
865
  return await rawWebSocket(
831
866
  this.#driver,
832
867
  target,
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  INTERNAL_ERROR_CODE,
3
3
  RivetError,
4
+ type ActorSpecifier,
4
5
  type RivetErrorLike,
5
6
  UserError,
6
7
  } from "@/actor/errors";
@@ -21,7 +22,7 @@ export class MalformedResponseMessage extends ActorClientError {
21
22
 
22
23
  export { RivetError, RivetError as ActorError, UserError };
23
24
  export type ActorSchedulingError = RivetError;
24
- export type { RivetErrorLike };
25
+ export type { ActorSpecifier, RivetErrorLike };
25
26
 
26
27
  export class HttpRequestError extends ActorClientError {
27
28
  constructor(message: string, opts?: { cause?: unknown }) {
@@ -12,6 +12,7 @@ import {
12
12
  type HttpQueueSendResponse as HttpQueueSendResponseJson,
13
13
  HttpQueueSendResponseSchema,
14
14
  } from "@/common/client-protocol-zod";
15
+ import type { JsonCompatValue } from "@/common/encoding";
15
16
  import { decodeCborCompat, encodeCborCompat } from "@/serde";
16
17
  import { bufferToArrayBuffer } from "@/utils";
17
18
  import { sendHttpRequest } from "./utils";
@@ -111,7 +112,7 @@ export function createQueueSender(
111
112
  }),
112
113
  requestToBare: (value): protocol.HttpQueueSendRequest => ({
113
114
  name: value.name ?? name,
114
- body: bufferToArrayBuffer(encodeCborCompat(value.body)),
115
+ body: bufferToArrayBuffer(encodeCborCompat(value.body as JsonCompatValue)),
115
116
  wait: value.wait ?? false,
116
117
  timeout:
117
118
  value.timeout !== undefined ? BigInt(value.timeout) : null,
@@ -96,13 +96,11 @@ export async function rawHttpFetch(
96
96
  return driver.sendRequest(target, proxyRequest, options);
97
97
  } catch (err) {
98
98
  // Standardize to ClientActorError instead of the native backend error
99
- const { group, code, message, metadata } = deconstructError(
99
+ const { group, code, message, metadata, actor } = deconstructError(
100
100
  err,
101
- logger(),
102
- {},
103
101
  true,
104
102
  );
105
- throw new ActorError(group, code, message, metadata);
103
+ throw new ActorError(group, code, message, { metadata, actor });
106
104
  }
107
105
  }
108
106
 
@@ -3,7 +3,6 @@ import type { VersionedDataHandler } from "vbare";
3
3
  import type { z } from "zod/v4";
4
4
  import type { Encoding } from "@/common/encoding";
5
5
  import { assertUnreachable } from "@/common/utils";
6
- import type { HttpResponseError } from "@/common/client-protocol";
7
6
  import { HTTP_RESPONSE_ERROR_VERSIONED } from "@/common/client-protocol-versioned";
8
7
  import {
9
8
  type HttpResponseError as HttpResponseErrorJson,
@@ -186,8 +185,16 @@ export async function sendHttpRequest<
186
185
  new Uint8Array(bufferResponse),
187
186
  HTTP_RESPONSE_ERROR_VERSIONED,
188
187
  HttpResponseErrorSchema,
189
- // JSON: metadata is already unknown
190
- (json): HttpResponseErrorJson => json as HttpResponseErrorJson,
188
+ // JSON/CBOR: normalize actor generation to the public number shape.
189
+ (json): any => ({
190
+ ...json,
191
+ actor: json.actor
192
+ ? {
193
+ ...json.actor,
194
+ generation: Number(json.actor.generation),
195
+ }
196
+ : undefined,
197
+ }),
191
198
  // BARE: decode ArrayBuffer metadata to unknown
192
199
  (bare): any => ({
193
200
  group: bare.group,
@@ -196,14 +203,35 @@ export async function sendHttpRequest<
196
203
  metadata: bare.metadata
197
204
  ? decodeCborCompat(new Uint8Array(bare.metadata))
198
205
  : undefined,
206
+ actor: bare.actor
207
+ ? {
208
+ actorId: bare.actor.actorId,
209
+ generation: Number(bare.actor.generation),
210
+ key: bare.actor.key ?? undefined,
211
+ }
212
+ : undefined,
199
213
  }),
200
214
  );
201
215
 
216
+ logger().warn({
217
+ msg: "http error response",
218
+ group: responseData.group,
219
+ code: responseData.code,
220
+ message: responseData.message,
221
+ metadata: responseData.metadata,
222
+ actorId: responseData.actor?.actorId,
223
+ generation: responseData.actor?.generation,
224
+ actorKey: responseData.actor?.key,
225
+ });
226
+
202
227
  throw new ActorError(
203
228
  responseData.group,
204
229
  responseData.code,
205
230
  responseData.message,
206
- responseData.metadata,
231
+ {
232
+ metadata: responseData.metadata,
233
+ actor: responseData.actor,
234
+ },
207
235
  );
208
236
  } catch (error) {
209
237
  // If it's already an ActorError, re-throw it
@@ -14,6 +14,8 @@ export const HEADER_ENCODING = "x-rivet-encoding";
14
14
  export const HEADER_CONN_PARAMS = "x-rivet-conn-params";
15
15
 
16
16
  export const HEADER_ACTOR_ID = "x-rivet-actor";
17
+ export const HEADER_ACTOR_GENERATION = "x-rivet-actor-generation";
18
+ export const HEADER_ACTOR_KEY = "x-rivet-actor-key";
17
19
 
18
20
  export const HEADER_RIVET_TOKEN = "x-rivet-token";
19
21
 
@@ -49,6 +51,8 @@ export const ALLOWED_PUBLIC_HEADERS = [
49
51
  HEADER_ENCODING,
50
52
  HEADER_CONN_PARAMS,
51
53
  HEADER_ACTOR_ID,
54
+ HEADER_ACTOR_GENERATION,
55
+ HEADER_ACTOR_KEY,
52
56
  HEADER_RIVET_TARGET,
53
57
  HEADER_RIVET_ACTOR,
54
58
  HEADER_RIVET_NAMESPACE,