@rowan-agent/agent 0.8.2 → 0.8.3

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/dist/index.d.ts CHANGED
@@ -1667,6 +1667,7 @@ declare class SqliteStore implements DurableStore {
1667
1667
  private persistState;
1668
1668
  private requireMatchingOwner;
1669
1669
  private immediateTransaction;
1670
+ private readTransaction;
1670
1671
  private assertOpen;
1671
1672
  }
1672
1673
 
package/dist/index.js CHANGED
@@ -3816,6 +3816,7 @@ var TransientRunEventHub = class {
3816
3816
  // src/runtime/durable-runtime.ts
3817
3817
  var DEFAULT_CONCURRENCY = 10;
3818
3818
  var DEFAULT_POLL_MS = 25;
3819
+ var MAX_CONSUMER_IDLE_POLL_MS = 250;
3819
3820
  var OWNER_LEASE_MS = 3e4;
3820
3821
  var OWNER_RENEWAL_MS = 1e4;
3821
3822
  var AgentRuntime = class _AgentRuntime {
@@ -4218,6 +4219,7 @@ var AgentRuntime = class _AgentRuntime {
4218
4219
  let cursor = registration.cursor;
4219
4220
  const waterline = cursorSequence(registration.waterline);
4220
4221
  let caughtUp = false;
4222
+ let pollMs = DEFAULT_POLL_MS;
4221
4223
  while (!subscription.controller.signal.aborted && !this.closed) {
4222
4224
  const events = await this.owned.listEvents(cursor ? { after: cursor } : {});
4223
4225
  for (const event of events) {
@@ -4243,7 +4245,8 @@ var AgentRuntime = class _AgentRuntime {
4243
4245
  caughtUp = true;
4244
4246
  subscription.caughtUp.resolve();
4245
4247
  }
4246
- await delay(DEFAULT_POLL_MS);
4248
+ pollMs = events.length === 0 ? Math.min(MAX_CONSUMER_IDLE_POLL_MS, pollMs * 2) : DEFAULT_POLL_MS;
4249
+ await delay(pollMs);
4247
4250
  }
4248
4251
  if (!caughtUp) subscription.caughtUp.resolve();
4249
4252
  }
@@ -5497,7 +5500,28 @@ var SqliteStore = class {
5497
5500
  return this.invoke(lease, (store, current) => store.listRuns(current, input), false);
5498
5501
  }
5499
5502
  async listEvents(lease, input = {}) {
5500
- return this.invoke(lease, (store, current) => store.listEvents(current, input), false);
5503
+ this.assertOpen();
5504
+ return this.readTransaction(() => {
5505
+ this.requireMatchingOwner(lease, true);
5506
+ const after = input.after ? parseEventCursor(lease, input.after) : 0;
5507
+ if (input.after) {
5508
+ const latest = this.database.query(
5509
+ "SELECT payload_json FROM run_events ORDER BY sequence DESC LIMIT 1"
5510
+ ).get();
5511
+ const waterline = latest ? parseEventCursor(
5512
+ lease,
5513
+ JSON.parse(latest.payload_json).cursor
5514
+ ) : 0;
5515
+ if (after > waterline) {
5516
+ throw new RuntimeError("invalid_cursor", { cursorType: "event", reason: "beyond_waterline" });
5517
+ }
5518
+ if (after === waterline) return [];
5519
+ }
5520
+ const rows = this.database.query(
5521
+ "SELECT payload_json FROM run_events ORDER BY sequence LIMIT -1 OFFSET ?"
5522
+ ).all(after);
5523
+ return rows.map((row) => JSON.parse(row.payload_json));
5524
+ });
5501
5525
  }
5502
5526
  async openConsumer(lease, consumerId) {
5503
5527
  return this.invoke(lease, (store, current) => store.openConsumer(current, consumerId), false);
@@ -5686,6 +5710,20 @@ var SqliteStore = class {
5686
5710
  throw error;
5687
5711
  }
5688
5712
  }
5713
+ readTransaction(operation) {
5714
+ this.database.run("BEGIN");
5715
+ try {
5716
+ const result = operation();
5717
+ this.database.run("COMMIT");
5718
+ return result;
5719
+ } catch (error) {
5720
+ try {
5721
+ this.database.run("ROLLBACK");
5722
+ } catch {
5723
+ }
5724
+ throw error;
5725
+ }
5726
+ }
5689
5727
  assertOpen() {
5690
5728
  if (this.closed) throw new RuntimeError("runtime_closed", null);
5691
5729
  }
@@ -5774,6 +5812,19 @@ function ownerLease(row) {
5774
5812
  expiresAt: new Date(row.expires_at).toISOString()
5775
5813
  };
5776
5814
  }
5815
+ function parseEventCursor(lease, cursor) {
5816
+ const value = String(cursor);
5817
+ const separator = value.lastIndexOf(":");
5818
+ const incarnation = separator < 0 ? "" : value.slice(0, separator);
5819
+ const sequence = separator < 0 ? "" : value.slice(separator + 1);
5820
+ const token = String(lease.token);
5821
+ const ownerSuffix = `:${lease.epoch}:${lease.ownerId}`;
5822
+ const expectedIncarnation = token.endsWith(ownerSuffix) ? token.slice(0, -ownerSuffix.length) : "";
5823
+ if (incarnation !== expectedIncarnation || !/^\d+$/.test(sequence)) {
5824
+ throw new RuntimeError("invalid_cursor", { cursorType: "event", reason: "wrong_store" });
5825
+ }
5826
+ return Number(sequence);
5827
+ }
5777
5828
  function ownershipLost2(lease, row) {
5778
5829
  return new RuntimeError("runtime_ownership_lost", {
5779
5830
  reason: row.epoch > lease.epoch ? "epoch_advanced" : row.owner_id ? "released" : "released",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowan-agent/agent",
3
- "version": "0.8.2",
3
+ "version": "0.8.3",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",