@springbrand/agent-runtime 0.3.0-alpha.21 → 0.3.0-alpha.22

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@springbrand/agent-runtime",
3
- "version": "0.3.0-alpha.21",
3
+ "version": "0.3.0-alpha.22",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src",
@@ -17,10 +17,10 @@
17
17
  "./models": "./src/lib/model-catalog.ts"
18
18
  },
19
19
  "dependencies": {
20
- "@cloudflare/codemode": "0.5.2",
20
+ "@cloudflare/codemode": "0.5.4",
21
21
  "@cloudflare/sandbox": "0.12.4",
22
22
  "@cloudflare/shell": "0.4.3",
23
- "@cloudflare/think": "0.18.0",
23
+ "@cloudflare/think": "0.20.2",
24
24
  "@earendil-works/pi-agent-core": "1.1.0",
25
25
  "@earendil-works/pi-ai": "1.1.0",
26
26
  "@types/lodash-es": "^4.17.12",
@@ -32,11 +32,11 @@
32
32
  "@earendil-works/chord": "1.1.0"
33
33
  },
34
34
  "peerDependencies": {
35
- "agents": "^0.23.0",
35
+ "agents": ">=0.28.1 <0.29.0",
36
36
  "ai": "^7.0.0"
37
37
  },
38
38
  "devDependencies": {
39
- "agents": "0.23.0",
39
+ "agents": "0.28.1",
40
40
  "ai": "7.0.56"
41
41
  }
42
42
  }
@@ -376,7 +376,7 @@ const TERMINAL_AGENT_TOOL_STATUSES = [
376
376
  "interrupted",
377
377
  ] as const;
378
378
  const AGENT_TOOL_RETENTION_MS = 24 * 60 * 60 * 1_000;
379
- const STABLE_RUNTIME_KEY_MIGRATION = "agent-runtime:stable-runtime-key-migration-v1";
379
+ export const STABLE_RUNTIME_KEY_MIGRATION = "agent-runtime:stable-runtime-key-migration-v1";
380
380
 
381
381
  function parseTemporaryAgentLaunch(input: unknown): TemporaryAgentLaunchSelection {
382
382
  const record = input != null && typeof input === "object"
@@ -597,7 +597,16 @@ export class SubmissionLifecycle<
597
597
  activate(submission: TSubmission, active: TActive): () => void {
598
598
  this.activeBySubmission.set(submission.submissionId, active);
599
599
  const latest = this.options.store.find(submission.submissionId);
600
- if (latest?.abortReason) this.options.abortActive(active);
600
+ if (latest?.abortReason) {
601
+ // The cancel is already committed; this abort only stops the executor and may lose to it settling.
602
+ void (async () => this.options.abortActive(active))().catch((error: unknown) => {
603
+ console.warn(
604
+ "[runtime-early-abort:failed]",
605
+ submission.submissionId,
606
+ error instanceof Error ? error.message : String(error),
607
+ );
608
+ });
609
+ }
601
610
  return () => {
602
611
  if (this.activeBySubmission.get(submission.submissionId) === active) {
603
612
  this.activeBySubmission.delete(submission.submissionId);
@@ -53,6 +53,7 @@ export class RuntimeTelemetryCoordinator {
53
53
  private delivery?: TelemetryDelivery;
54
54
  private configured = false;
55
55
  private draining?: Promise<void>;
56
+ private drainRequested = false;
56
57
  private readonly coldBuffer: BufferedTelemetryFact[] = [];
57
58
 
58
59
  constructor(
@@ -182,11 +183,19 @@ export class RuntimeTelemetryCoordinator {
182
183
  }
183
184
 
184
185
  private queueDrain(): void {
185
- if (!this.delivery || this.draining) return;
186
+ if (!this.delivery) return;
187
+ // A drain reads its batch before publishing; facts written after that wait for the next one.
188
+ if (this.draining) {
189
+ this.drainRequested = true;
190
+ return;
191
+ }
192
+ this.drainRequested = false;
186
193
  const pending = this.drain();
187
194
  let tracked: Promise<void>;
188
195
  tracked = pending.finally(() => {
189
- if (this.draining === tracked) this.draining = undefined;
196
+ if (this.draining !== tracked) return;
197
+ this.draining = undefined;
198
+ if (this.drainRequested) this.queueDrain();
190
199
  });
191
200
  this.draining = tracked;
192
201
  this.options.waitUntil(tracked);
@@ -196,7 +205,8 @@ export class RuntimeTelemetryCoordinator {
196
205
  if (!this.delivery) return;
197
206
  try {
198
207
  const result = await this.delivery.drain();
199
- if (!result.hasPending) return;
208
+ // A queued follow-up drain schedules its own retry if it still leaves work.
209
+ if (!result.hasPending || this.drainRequested) return;
200
210
  await this.options.scheduleRetry(
201
211
  TELEMETRY_RETRY_DELAY_MS / 1_000,
202
212
  idempotentRetry,