@astralform/js 7.5.0 → 7.5.1

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.cts CHANGED
@@ -566,7 +566,7 @@ interface Conversation {
566
566
  /**
567
567
  * The project this task belongs to (`owner/repo`), or `null` for an ordinary
568
568
  * conversation. Set on the first turn and immutable after. Absent (rather than
569
- * null) from an Astralform older than 0.70.0.
569
+ * null) from an Astralform older than 0.69.46.
570
570
  */
571
571
  repository?: string | null;
572
572
  }
@@ -625,7 +625,7 @@ interface AgentInfo {
625
625
  * Derived by the server from the connector, so it cannot go stale the way the
626
626
  * retired `mode` toggle could. It gates a SURFACE, not an ability: naming a
627
627
  * repository is optional on every task, and a task that names none is an
628
- * ordinary chat. Absent on Astralform older than 0.71.0 — fall back to `mode`
628
+ * ordinary chat. Absent on Astralform older than 0.69.50 — fall back to `mode`
629
629
  * there.
630
630
  *
631
631
  * It is a property of the WORKSPACE, not of a persona: `GET /v1/agents` selects
@@ -778,9 +778,9 @@ interface ChatStreamRequest {
778
778
  * later turn may omit it or repeat the same value; a DIFFERENT value is refused
779
779
  * (409), not ignored — a task is bound to one repository for life, so a
780
780
  * different repository means a new task. A task that never names one is an
781
- * ordinary chat; since Astralform 0.71.0 there is no agent mode that requires
781
+ * ordinary chat; since Astralform 0.69.50 there is no agent mode that requires
782
782
  * one.
783
- * Astralform >= 0.70.0.
783
+ * Astralform >= 0.69.46.
784
784
  */
785
785
  repository?: string;
786
786
  mcp_manifest?: ToolDefinition[];
@@ -1085,8 +1085,8 @@ interface SendOptions$1 extends ModelChoiceOptions {
1085
1085
  * Send it on the turn that STARTS a task; the binding is write-once, so a
1086
1086
  * later turn may omit it or repeat the same value, and a DIFFERENT value is
1087
1087
  * refused (409) rather than ignored. Omit it entirely and the task is an
1088
- * ordinary chat — since Astralform 0.71.0 no agent requires one, and a first
1089
- * turn without it is no longer a 400. Astralform >= 0.70.0.
1088
+ * ordinary chat — since Astralform 0.69.50 no agent requires one, and a first
1089
+ * turn without it is no longer a 400. Astralform >= 0.69.46.
1090
1090
  */
1091
1091
  repository?: string;
1092
1092
  }
@@ -1845,8 +1845,8 @@ interface SendOptions extends ModelChoiceOptions {
1845
1845
  * repeat the same value, and a DIFFERENT value is refused (409) rather than
1846
1846
  * ignored — silently acting on the wrong repository is the failure that rule
1847
1847
  * exists to prevent. Omit it entirely and the task is an ordinary chat: since
1848
- * Astralform 0.71.0 there is no agent mode that requires one, so a first turn
1849
- * without it is no longer a 400. Astralform >= 0.70.0.
1848
+ * Astralform 0.69.50 there is no agent mode that requires one, so a first turn
1849
+ * without it is no longer a 400. Astralform >= 0.69.46.
1850
1850
  */
1851
1851
  repository?: string;
1852
1852
  }
@@ -2018,6 +2018,14 @@ declare class StreamManager {
2018
2018
  */
2019
2019
  private settleIdle;
2020
2020
  private finalizeStream;
2021
+ /**
2022
+ * A conversation's turns, oldest first.
2023
+ *
2024
+ * Its own method so ``restore`` can put the request on the wire beside the
2025
+ * probe and the message list while ``replayHistory``, which consumes it,
2026
+ * keeps owning the shape it reads.
2027
+ */
2028
+ private jobList;
2021
2029
  private restore;
2022
2030
  /**
2023
2031
  * Has a live turn taken the block view over?
@@ -2056,6 +2064,12 @@ declare class StreamManager {
2056
2064
  * that started it, which is emitted as a bubble with no events — the whole
2057
2065
  * reason a conversation reopened mid-turn now shows the message that started
2058
2066
  * that turn.
2067
+ *
2068
+ * ``jobsRequest`` is the job list already IN FLIGHT — issued by ``restore``
2069
+ * alongside the probe and the message list rather than fetched here, so the
2070
+ * three round trips overlap. It is awaited inside the try below, which is
2071
+ * what keeps a failed job list non-blocking exactly as it was when the fetch
2072
+ * lived here.
2059
2073
  */
2060
2074
  private replayHistory;
2061
2075
  private setActiveConversation;
package/dist/index.d.ts CHANGED
@@ -566,7 +566,7 @@ interface Conversation {
566
566
  /**
567
567
  * The project this task belongs to (`owner/repo`), or `null` for an ordinary
568
568
  * conversation. Set on the first turn and immutable after. Absent (rather than
569
- * null) from an Astralform older than 0.70.0.
569
+ * null) from an Astralform older than 0.69.46.
570
570
  */
571
571
  repository?: string | null;
572
572
  }
@@ -625,7 +625,7 @@ interface AgentInfo {
625
625
  * Derived by the server from the connector, so it cannot go stale the way the
626
626
  * retired `mode` toggle could. It gates a SURFACE, not an ability: naming a
627
627
  * repository is optional on every task, and a task that names none is an
628
- * ordinary chat. Absent on Astralform older than 0.71.0 — fall back to `mode`
628
+ * ordinary chat. Absent on Astralform older than 0.69.50 — fall back to `mode`
629
629
  * there.
630
630
  *
631
631
  * It is a property of the WORKSPACE, not of a persona: `GET /v1/agents` selects
@@ -778,9 +778,9 @@ interface ChatStreamRequest {
778
778
  * later turn may omit it or repeat the same value; a DIFFERENT value is refused
779
779
  * (409), not ignored — a task is bound to one repository for life, so a
780
780
  * different repository means a new task. A task that never names one is an
781
- * ordinary chat; since Astralform 0.71.0 there is no agent mode that requires
781
+ * ordinary chat; since Astralform 0.69.50 there is no agent mode that requires
782
782
  * one.
783
- * Astralform >= 0.70.0.
783
+ * Astralform >= 0.69.46.
784
784
  */
785
785
  repository?: string;
786
786
  mcp_manifest?: ToolDefinition[];
@@ -1085,8 +1085,8 @@ interface SendOptions$1 extends ModelChoiceOptions {
1085
1085
  * Send it on the turn that STARTS a task; the binding is write-once, so a
1086
1086
  * later turn may omit it or repeat the same value, and a DIFFERENT value is
1087
1087
  * refused (409) rather than ignored. Omit it entirely and the task is an
1088
- * ordinary chat — since Astralform 0.71.0 no agent requires one, and a first
1089
- * turn without it is no longer a 400. Astralform >= 0.70.0.
1088
+ * ordinary chat — since Astralform 0.69.50 no agent requires one, and a first
1089
+ * turn without it is no longer a 400. Astralform >= 0.69.46.
1090
1090
  */
1091
1091
  repository?: string;
1092
1092
  }
@@ -1845,8 +1845,8 @@ interface SendOptions extends ModelChoiceOptions {
1845
1845
  * repeat the same value, and a DIFFERENT value is refused (409) rather than
1846
1846
  * ignored — silently acting on the wrong repository is the failure that rule
1847
1847
  * exists to prevent. Omit it entirely and the task is an ordinary chat: since
1848
- * Astralform 0.71.0 there is no agent mode that requires one, so a first turn
1849
- * without it is no longer a 400. Astralform >= 0.70.0.
1848
+ * Astralform 0.69.50 there is no agent mode that requires one, so a first turn
1849
+ * without it is no longer a 400. Astralform >= 0.69.46.
1850
1850
  */
1851
1851
  repository?: string;
1852
1852
  }
@@ -2018,6 +2018,14 @@ declare class StreamManager {
2018
2018
  */
2019
2019
  private settleIdle;
2020
2020
  private finalizeStream;
2021
+ /**
2022
+ * A conversation's turns, oldest first.
2023
+ *
2024
+ * Its own method so ``restore`` can put the request on the wire beside the
2025
+ * probe and the message list while ``replayHistory``, which consumes it,
2026
+ * keeps owning the shape it reads.
2027
+ */
2028
+ private jobList;
2021
2029
  private restore;
2022
2030
  /**
2023
2031
  * Has a live turn taken the block view over?
@@ -2056,6 +2064,12 @@ declare class StreamManager {
2056
2064
  * that started it, which is emitted as a bubble with no events — the whole
2057
2065
  * reason a conversation reopened mid-turn now shows the message that started
2058
2066
  * that turn.
2067
+ *
2068
+ * ``jobsRequest`` is the job list already IN FLIGHT — issued by ``restore``
2069
+ * alongside the probe and the message list rather than fetched here, so the
2070
+ * three round trips overlap. It is awaited inside the try below, which is
2071
+ * what keeps a failed job list non-blocking exactly as it was when the fetch
2072
+ * lived here.
2059
2073
  */
2060
2074
  private replayHistory;
2061
2075
  private setActiveConversation;
package/dist/index.js CHANGED
@@ -2887,23 +2887,41 @@ var StreamManager = class {
2887
2887
  }
2888
2888
  }
2889
2889
  // ── Internal: restore ─────────────────────────────────────────
2890
+ /**
2891
+ * A conversation's turns, oldest first.
2892
+ *
2893
+ * Its own method so ``restore`` can put the request on the wire beside the
2894
+ * probe and the message list while ``replayHistory``, which consumes it,
2895
+ * keeps owning the shape it reads.
2896
+ */
2897
+ jobList(conversationId) {
2898
+ return this.session.client.get(
2899
+ `/v1/conversations/${encodeURIComponent(conversationId)}/jobs`
2900
+ );
2901
+ }
2890
2902
  async restore(conversationId, gen) {
2891
2903
  const superseded = () => gen !== this.generation;
2892
2904
  if (superseded()) return;
2893
2905
  const turn = this.turnCounter;
2894
2906
  const announcedRestoring = !this.session.isStreaming;
2895
2907
  if (announcedRestoring) this.setState("restoring");
2896
- let activeJobId = null;
2897
- try {
2898
- const res = await this.session.client.getActiveJob(conversationId);
2899
- activeJobId = res.jobId;
2900
- } catch {
2901
- }
2902
2908
  if (superseded()) return;
2903
- await this.session.loadConversation(conversationId);
2909
+ const probeRequest = this.session.client.getActiveJob(conversationId).catch(() => null);
2910
+ const loadRequest = this.session.loadConversation(conversationId);
2911
+ const jobsRequest = announcedRestoring ? this.jobList(conversationId) : null;
2912
+ void jobsRequest?.catch(() => {
2913
+ });
2914
+ const [probe] = await Promise.all([probeRequest, loadRequest]);
2915
+ const activeJobId = probe?.jobId ?? null;
2904
2916
  if (superseded()) return;
2905
2917
  if (announcedRestoring && this.viewTakenOverByLiveTurn()) return;
2906
- if (announcedRestoring && !await this.replayHistory(conversationId, gen, activeJobId, turn))
2918
+ if (jobsRequest && !await this.replayHistory(
2919
+ conversationId,
2920
+ gen,
2921
+ activeJobId,
2922
+ turn,
2923
+ jobsRequest
2924
+ ))
2907
2925
  return;
2908
2926
  if (activeJobId) {
2909
2927
  this.setState("streaming");
@@ -2961,11 +2979,17 @@ var StreamManager = class {
2961
2979
  * that started it, which is emitted as a bubble with no events — the whole
2962
2980
  * reason a conversation reopened mid-turn now shows the message that started
2963
2981
  * that turn.
2982
+ *
2983
+ * ``jobsRequest`` is the job list already IN FLIGHT — issued by ``restore``
2984
+ * alongside the probe and the message list rather than fetched here, so the
2985
+ * three round trips overlap. It is awaited inside the try below, which is
2986
+ * what keeps a failed job list non-blocking exactly as it was when the fetch
2987
+ * lived here.
2964
2988
  */
2965
- async replayHistory(conversationId, gen, activeJobId, turn) {
2989
+ async replayHistory(conversationId, gen, activeJobId, turn, jobsRequest) {
2966
2990
  const stopReplay = () => gen !== this.generation || this.viewTakenOverByLiveTurn() || this.turnStarted(turn);
2967
2991
  try {
2968
- const jobs = await this.session.client.get(`/v1/conversations/${encodeURIComponent(conversationId)}/jobs`);
2992
+ const jobs = await jobsRequest;
2969
2993
  if (stopReplay()) return false;
2970
2994
  const replayableJobs = jobs.filter(
2971
2995
  (j) => j.job_id !== activeJobId