@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.cjs +34 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -8
- package/dist/index.d.ts +22 -8
- package/dist/index.js +34 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2938,23 +2938,41 @@ var StreamManager = class {
|
|
|
2938
2938
|
}
|
|
2939
2939
|
}
|
|
2940
2940
|
// ── Internal: restore ─────────────────────────────────────────
|
|
2941
|
+
/**
|
|
2942
|
+
* A conversation's turns, oldest first.
|
|
2943
|
+
*
|
|
2944
|
+
* Its own method so ``restore`` can put the request on the wire beside the
|
|
2945
|
+
* probe and the message list while ``replayHistory``, which consumes it,
|
|
2946
|
+
* keeps owning the shape it reads.
|
|
2947
|
+
*/
|
|
2948
|
+
jobList(conversationId) {
|
|
2949
|
+
return this.session.client.get(
|
|
2950
|
+
`/v1/conversations/${encodeURIComponent(conversationId)}/jobs`
|
|
2951
|
+
);
|
|
2952
|
+
}
|
|
2941
2953
|
async restore(conversationId, gen) {
|
|
2942
2954
|
const superseded = () => gen !== this.generation;
|
|
2943
2955
|
if (superseded()) return;
|
|
2944
2956
|
const turn = this.turnCounter;
|
|
2945
2957
|
const announcedRestoring = !this.session.isStreaming;
|
|
2946
2958
|
if (announcedRestoring) this.setState("restoring");
|
|
2947
|
-
let activeJobId = null;
|
|
2948
|
-
try {
|
|
2949
|
-
const res = await this.session.client.getActiveJob(conversationId);
|
|
2950
|
-
activeJobId = res.jobId;
|
|
2951
|
-
} catch {
|
|
2952
|
-
}
|
|
2953
2959
|
if (superseded()) return;
|
|
2954
|
-
|
|
2960
|
+
const probeRequest = this.session.client.getActiveJob(conversationId).catch(() => null);
|
|
2961
|
+
const loadRequest = this.session.loadConversation(conversationId);
|
|
2962
|
+
const jobsRequest = announcedRestoring ? this.jobList(conversationId) : null;
|
|
2963
|
+
void jobsRequest?.catch(() => {
|
|
2964
|
+
});
|
|
2965
|
+
const [probe] = await Promise.all([probeRequest, loadRequest]);
|
|
2966
|
+
const activeJobId = probe?.jobId ?? null;
|
|
2955
2967
|
if (superseded()) return;
|
|
2956
2968
|
if (announcedRestoring && this.viewTakenOverByLiveTurn()) return;
|
|
2957
|
-
if (
|
|
2969
|
+
if (jobsRequest && !await this.replayHistory(
|
|
2970
|
+
conversationId,
|
|
2971
|
+
gen,
|
|
2972
|
+
activeJobId,
|
|
2973
|
+
turn,
|
|
2974
|
+
jobsRequest
|
|
2975
|
+
))
|
|
2958
2976
|
return;
|
|
2959
2977
|
if (activeJobId) {
|
|
2960
2978
|
this.setState("streaming");
|
|
@@ -3012,11 +3030,17 @@ var StreamManager = class {
|
|
|
3012
3030
|
* that started it, which is emitted as a bubble with no events — the whole
|
|
3013
3031
|
* reason a conversation reopened mid-turn now shows the message that started
|
|
3014
3032
|
* that turn.
|
|
3033
|
+
*
|
|
3034
|
+
* ``jobsRequest`` is the job list already IN FLIGHT — issued by ``restore``
|
|
3035
|
+
* alongside the probe and the message list rather than fetched here, so the
|
|
3036
|
+
* three round trips overlap. It is awaited inside the try below, which is
|
|
3037
|
+
* what keeps a failed job list non-blocking exactly as it was when the fetch
|
|
3038
|
+
* lived here.
|
|
3015
3039
|
*/
|
|
3016
|
-
async replayHistory(conversationId, gen, activeJobId, turn) {
|
|
3040
|
+
async replayHistory(conversationId, gen, activeJobId, turn, jobsRequest) {
|
|
3017
3041
|
const stopReplay = () => gen !== this.generation || this.viewTakenOverByLiveTurn() || this.turnStarted(turn);
|
|
3018
3042
|
try {
|
|
3019
|
-
const jobs = await
|
|
3043
|
+
const jobs = await jobsRequest;
|
|
3020
3044
|
if (stopReplay()) return false;
|
|
3021
3045
|
const replayableJobs = jobs.filter(
|
|
3022
3046
|
(j) => j.job_id !== activeJobId
|