experimental-a2 0.19.0 → 0.20.0

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 (95) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/actor.js +1 -1
  3. package/dist/ai-fx.d.ts.map +1 -1
  4. package/dist/ai-fx.js +34 -4
  5. package/dist/ai-fx.js.map +1 -1
  6. package/dist/ai-harness-CV6rXbB3.d.ts.map +1 -1
  7. package/dist/{ai-harness-BuuC-gJ3.js → ai-harness-Clbg5ei7.js} +11 -2
  8. package/dist/ai-harness-Clbg5ei7.js.map +1 -0
  9. package/dist/ai-pi.js +2 -2
  10. package/dist/ai-server.d.ts.map +1 -1
  11. package/dist/ai-server.js +6 -4
  12. package/dist/ai-server.js.map +1 -1
  13. package/dist/internal-CscSY7K_.js.map +1 -1
  14. package/dist/scheduler-qstash.d.ts.map +1 -1
  15. package/dist/scheduler-qstash.js +5 -5
  16. package/dist/scheduler-qstash.js.map +1 -1
  17. package/dist/scheduler-vercel.d.ts.map +1 -1
  18. package/dist/scheduler-vercel.js +4 -3
  19. package/dist/scheduler-vercel.js.map +1 -1
  20. package/dist/server-DYAATFuT.d.ts.map +1 -1
  21. package/dist/{server-D-Y4pqwu.js → server-qyb5aJJG.js} +39 -25
  22. package/dist/server-qyb5aJJG.js.map +1 -0
  23. package/dist/server.js +1 -1
  24. package/dist/session-clear-DGI4jTQ5.js.map +1 -1
  25. package/dist/store-postgres.d.ts.map +1 -1
  26. package/dist/store-postgres.js +38 -136
  27. package/dist/store-postgres.js.map +1 -1
  28. package/docs/01-quickstart.mdx +7 -4
  29. package/docs/actors/01-introduction.mdx +1 -1
  30. package/docs/actors/meta.ts +1 -1
  31. package/docs/agents/02-tools.mdx +1 -1
  32. package/docs/agents/03-conversations.mdx +1 -1
  33. package/docs/agents/meta.ts +1 -1
  34. package/docs/client/meta.ts +1 -1
  35. package/docs/contract/03-sessions.mdx +1 -1
  36. package/docs/index.mdx +2 -2
  37. package/docs/reference/01-core.mdx +8 -8
  38. package/docs/reference/02-server.mdx +3 -3
  39. package/docs/reference/04-ai.mdx +9 -1
  40. package/docs/reference/05-telemetry.mdx +132 -0
  41. package/docs/reference/06-errors.mdx +1 -1
  42. package/docs/reference/meta.ts +1 -1
  43. package/docs/schedulers/01-overview.mdx +112 -0
  44. package/docs/schedulers/02-vercel-queues.mdx +87 -0
  45. package/docs/schedulers/03-qstash.mdx +123 -0
  46. package/docs/schedulers/meta.ts +1 -0
  47. package/docs/server/01-handlers.mdx +29 -2
  48. package/docs/server/02-timers.mdx +2 -2
  49. package/docs/server/06-guarantees.mdx +6 -3
  50. package/docs/stores/01-overview.mdx +37 -0
  51. package/docs/stores/02-redis.mdx +49 -0
  52. package/docs/stores/03-redis-http.mdx +56 -0
  53. package/docs/stores/04-postgres.mdx +121 -0
  54. package/docs/stores/05-sqlite.mdx +34 -0
  55. package/docs/stores/06-memory.mdx +22 -0
  56. package/docs/stores/meta.ts +1 -0
  57. package/examples/playground/DEPLOY.md +12 -7
  58. package/examples/playground/app/a0/apps/[appId]/route.ts +6 -10
  59. package/examples/playground/app/a0/chat.test.tsx +421 -330
  60. package/examples/playground/app/a0/shell.tsx +1 -1
  61. package/examples/playground/app/a0/uploads/route.test.ts +59 -0
  62. package/examples/playground/app/agent/[agentId]/agent-queue.test.tsx +116 -90
  63. package/examples/playground/app/agent/[agentId]/compaction-panel.test.tsx +107 -76
  64. package/examples/playground/app/agent/ingress.test.ts +41 -17
  65. package/examples/playground/app/agent/model-input.test.tsx +92 -43
  66. package/examples/playground/app/chat/[chatId]/agent-stream-drawer.test.tsx +2 -2
  67. package/examples/playground/app/chat/server.test.ts +38 -65
  68. package/examples/playground/app/components/activity-history.test.tsx +60 -18
  69. package/examples/playground/app/components/fast-link.test.tsx +3 -5
  70. package/examples/playground/app/initial-state.test.tsx +86 -45
  71. package/examples/playground/package.json +2 -1
  72. package/examples/playground/test/agent.ts +35 -0
  73. package/examples/playground/test/model.ts +149 -0
  74. package/examples/playground/test/serve.ts +184 -0
  75. package/examples/playground/test/server-only.ts +1 -0
  76. package/examples/playground/vitest.config.ts +27 -0
  77. package/package.json +3 -1
  78. package/sql/postgres/notifications.sql +24 -0
  79. package/sql/postgres/schema.sql +137 -0
  80. package/src/ai-agent.ts +5 -4
  81. package/src/ai-fx.ts +37 -3
  82. package/src/ai-harness.ts +18 -0
  83. package/src/errors.ts +1 -1
  84. package/src/internal.ts +2 -1
  85. package/src/postgres-notifications.ts +0 -22
  86. package/src/postgres-resources.ts +6 -9
  87. package/src/postgres-schema.ts +80 -0
  88. package/src/scheduler-qstash.ts +12 -5
  89. package/src/scheduler-vercel.ts +10 -4
  90. package/src/server.ts +66 -32
  91. package/src/store-postgres.ts +5 -123
  92. package/dist/ai-harness-BuuC-gJ3.js.map +0 -1
  93. package/dist/server-D-Y4pqwu.js.map +0 -1
  94. package/docs/reference/05-adapters.mdx +0 -351
  95. package/docs/server/05-production.mdx +0 -323
@@ -1386,7 +1386,10 @@ function createServer(options) {
1386
1386
  const signal = createDrainSignal();
1387
1387
  const p = new Promise((resolve) => {
1388
1388
  queueMicrotask(() => {
1389
- drainSession(sessionId, watchdogDueAt, signal).then(() => resolve()).catch(() => resolve());
1389
+ drainSession(sessionId, {
1390
+ watchdogDueAt,
1391
+ signal
1392
+ }).then(() => resolve()).catch(() => resolve());
1390
1393
  });
1391
1394
  }).finally(() => {
1392
1395
  if (scheduledDrains.get(sessionId)?.promise === p) scheduledDrains.delete(sessionId);
@@ -2551,7 +2554,7 @@ function createServer(options) {
2551
2554
  }
2552
2555
  }));
2553
2556
  };
2554
- const drainSession = (sessionId, watchdogDueAt, signal) => telemetry.span("a2.drain", {
2557
+ const drainSession = (sessionId, { watchdogDueAt, signal, handOffFailure = false } = {}) => telemetry.span("a2.drain", {
2555
2558
  "a2.contract": name,
2556
2559
  "a2.session_id": sessionId
2557
2560
  }, async (span) => {
@@ -2671,7 +2674,8 @@ function createServer(options) {
2671
2674
  }, async (eventSpan) => {
2672
2675
  let subscription;
2673
2676
  let handlerSignal = supersedeSignal;
2674
- let returned;
2677
+ let completion;
2678
+ let completing = false;
2675
2679
  try {
2676
2680
  if (registration?.abortOn) {
2677
2681
  subscription = await subscribeAbort(store, ns, event, registration.abortOn, event.attemptCount);
@@ -2683,7 +2687,25 @@ function createServer(options) {
2683
2687
  await subscription.close();
2684
2688
  subscription = void 0;
2685
2689
  }
2686
- returned = await returnedEvents(sessionId, event, result);
2690
+ const returned = await returnedEvents(sessionId, event, result);
2691
+ await renewal;
2692
+ completing = true;
2693
+ completion = await telemetry.span("a2.commit", {
2694
+ "a2.contract": name,
2695
+ "a2.session_id": sessionId,
2696
+ "a2.commit.operation": "complete",
2697
+ "a2.commit.index": event.index,
2698
+ "a2.commit.attempt": event.attemptCount
2699
+ }, async (commitSpan) => {
2700
+ const committed = await store.completeAttempt({
2701
+ sessionId: ns,
2702
+ index: event.index,
2703
+ attempt: event.attemptCount,
2704
+ events: returned
2705
+ });
2706
+ commitSpan.setAttribute("a2.commit.outcome", committed.outcome);
2707
+ return committed;
2708
+ });
2687
2709
  } catch (err) {
2688
2710
  if (supersedeSignal.aborted && err === supersedeSignal.reason) {
2689
2711
  eventSpan.setAttribute("a2.event.outcome", "surrendered");
@@ -2693,6 +2715,8 @@ function createServer(options) {
2693
2715
  appendsEvents: false
2694
2716
  };
2695
2717
  }
2718
+ const refused = completing && err instanceof A2Error && err.code === "PARTIAL_DUPLICATE_BATCH";
2719
+ if (completing && !refused) throw err;
2696
2720
  eventSpan.recordError(err);
2697
2721
  const failure = await telemetry.span("a2.commit", {
2698
2722
  "a2.contract": name,
@@ -2706,7 +2730,7 @@ function createServer(options) {
2706
2730
  index: event.index,
2707
2731
  attempt: event.attemptCount,
2708
2732
  error: describeError(err),
2709
- maxFailures: err instanceof NonRetriableError ? 1 : MAX_FAILURES,
2733
+ maxFailures: err instanceof NonRetriableError || refused ? 1 : MAX_FAILURES,
2710
2734
  retryAfterMs: failureRetryDelayMs(event.failureCount + 1)
2711
2735
  });
2712
2736
  commitSpan.setAttribute("a2.commit.outcome", result.outcome);
@@ -2721,23 +2745,6 @@ function createServer(options) {
2721
2745
  } finally {
2722
2746
  await subscription?.close();
2723
2747
  }
2724
- await renewal;
2725
- const completion = await telemetry.span("a2.commit", {
2726
- "a2.contract": name,
2727
- "a2.session_id": sessionId,
2728
- "a2.commit.operation": "complete",
2729
- "a2.commit.index": event.index,
2730
- "a2.commit.attempt": event.attemptCount
2731
- }, async (commitSpan) => {
2732
- const result = await store.completeAttempt({
2733
- sessionId: ns,
2734
- index: event.index,
2735
- attempt: event.attemptCount,
2736
- events: returned
2737
- });
2738
- commitSpan.setAttribute("a2.commit.outcome", result.outcome);
2739
- return result;
2740
- });
2741
2748
  eventSpan.setAttribute("a2.event.outcome", completion.outcome === "completed" ? "processed" : completion.outcome);
2742
2749
  if (completion.outcome === "superseded") return {
2743
2750
  status: "superseded",
@@ -2748,7 +2755,7 @@ function createServer(options) {
2748
2755
  return {
2749
2756
  status: "processed",
2750
2757
  opensLane: event.lane !== null,
2751
- appendsEvents: returned.length > 0
2758
+ appendsEvents: completion.events.length > 0
2752
2759
  };
2753
2760
  });
2754
2761
  };
@@ -2860,6 +2867,10 @@ function createServer(options) {
2860
2867
  if (signal) signal.closed = true;
2861
2868
  break;
2862
2869
  }
2870
+ } catch (error) {
2871
+ if (!handOffFailure || schedulerArm === void 0) throw error;
2872
+ span.recordError(error);
2873
+ outcome = "failed";
2863
2874
  } finally {
2864
2875
  if (signal) signal.closed = true;
2865
2876
  stopRenewing = true;
@@ -2920,7 +2931,10 @@ function createServer(options) {
2920
2931
  },
2921
2932
  schedulerDrain: (sessionId, opts) => {
2922
2933
  assertSessionId(sessionId);
2923
- return drainSession(sessionId, opts?.watchdogDueAt);
2934
+ return drainSession(sessionId, {
2935
+ watchdogDueAt: opts?.watchdogDueAt,
2936
+ handOffFailure: true
2937
+ });
2924
2938
  },
2925
2939
  schedulerAppend: async (sessionId, events, originIndex) => {
2926
2940
  if (!scheduler) throw new TypeError("scheduled append delivery requires a configured scheduler adapter");
@@ -3049,4 +3063,4 @@ const stateCacheKey = (sessionId, reducerName) => `${sessionId}\u0000${reducerNa
3049
3063
  //#endregion
3050
3064
  export { CONSOLE_TELEMETRY as a, parsePresenceSibling as c, handler as i, deliverSchedulerAppend as n, setServerFetchHooks as o, deliverSchedulerClear as r, sseResponse as s, createServer as t };
3051
3065
 
3052
- //# sourceMappingURL=server-D-Y4pqwu.js.map
3066
+ //# sourceMappingURL=server-qyb5aJJG.js.map