@astralform/js 6.0.2 → 6.0.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.js CHANGED
@@ -2711,15 +2711,15 @@ var StreamManager = class {
2711
2711
  try {
2712
2712
  const jobs = await this.session.client.get(`/v1/conversations/${encodeURIComponent(conversationId)}/jobs`);
2713
2713
  if (stopReplay()) return false;
2714
- const completedJobs = jobs.filter(
2715
- (j) => j.status === "completed" && j.job_id !== activeJobId
2714
+ const replayableJobs = jobs.filter(
2715
+ (j) => j.job_id !== activeJobId
2716
2716
  );
2717
2717
  const userMessages = this.session.messages.filter(
2718
2718
  (m) => m.role === "user"
2719
2719
  );
2720
2720
  const runningJob = activeJobId ? jobs.find((j) => j.job_id === activeJobId) : void 0;
2721
2721
  const plan = planRestore({
2722
- completedJobs: completedJobs.map((j) => ({
2722
+ completedJobs: replayableJobs.map((j) => ({
2723
2723
  job_id: j.job_id,
2724
2724
  message_id: j.message_id
2725
2725
  })),
@@ -2727,27 +2727,38 @@ var StreamManager = class {
2727
2727
  job_id: runningJob.job_id,
2728
2728
  message_id: runningJob.message_id
2729
2729
  },
2730
- // Completed jobs PLUS the ones still going. A send landing in the
2731
- // probe window has a running job, so its prompt is claimed and does
2732
- // not read as a steer replayed over the bubble the live send already
2733
- // rendered. Failed and cancelled jobs are deliberately NOT claimed:
2734
- // they produce no `turn` step, so claiming them would delete the
2735
- // user's prompt from the restore entirely rather than show it as a
2736
- // steer.
2737
- claimedMessageIds: jobs.filter((j) => j.status !== "failed" && j.status !== "cancelled").map((j) => j.message_id),
2730
+ // EVERY job, which is the same set the replay walk gets. The claim set
2731
+ // answers one question "will some turn step already draw this prompt?"
2732
+ // so it is a RESTATEMENT of the walk, and the two drifting apart is
2733
+ // what produces either a missing bubble or a doubled one.
2734
+ //
2735
+ // Failed and cancelled were excluded here for exactly one reason: they
2736
+ // produced no turn step, which is the bug fixed above. Now that they do,
2737
+ // the exclusion has no case left to describe.
2738
+ //
2739
+ // Being precise about what this change does and does not do: it is not
2740
+ // load-bearing TODAY. `planRestore` anchors a prompt at the index its
2741
+ // job links to and advances the cursor past it, so a message claimed by
2742
+ // a job inside the walk is never offered to the steer branch anyway —
2743
+ // the two spellings agree on current inputs. It is here because the
2744
+ // invariant is what keeps them agreeing: narrow the walk again without
2745
+ // narrowing this, and the prompts of the jobs dropped from it go with
2746
+ // them, silently. Deriving both from `jobs` makes that impossible to
2747
+ // get half-right.
2748
+ claimedMessageIds: jobs.map((j) => j.message_id),
2738
2749
  userMessages: userMessages.map((m) => ({
2739
2750
  id: m.id,
2740
2751
  content: m.content
2741
2752
  }))
2742
2753
  });
2743
2754
  const eventLists = await Promise.all(
2744
- completedJobs.map(
2755
+ replayableJobs.map(
2745
2756
  (job) => this.session.client.getConversationEvents(conversationId, job.job_id).catch(() => [])
2746
2757
  )
2747
2758
  );
2748
2759
  if (stopReplay()) return false;
2749
2760
  const eventsByJobId = new Map(
2750
- completedJobs.map((job, i) => [job.job_id, eventLists[i] ?? []])
2761
+ replayableJobs.map((job, i) => [job.job_id, eventLists[i] ?? []])
2751
2762
  );
2752
2763
  for (const step of plan) {
2753
2764
  if (stopReplay()) return false;
@@ -2769,11 +2780,14 @@ var StreamManager = class {
2769
2780
  );
2770
2781
  }
2771
2782
  if (stopReplay()) return false;
2772
- if (completedJobs.length > 0) {
2783
+ const versionCount = replayableJobs.filter(
2784
+ (j) => j.status === "completed"
2785
+ ).length;
2786
+ if (versionCount > 0) {
2773
2787
  this.emit({
2774
2788
  type: "versionsReady",
2775
2789
  conversationId,
2776
- count: completedJobs.length
2790
+ count: versionCount
2777
2791
  });
2778
2792
  }
2779
2793
  } catch {