@astralform/js 7.4.1 → 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 +45 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -32
- package/dist/index.d.ts +65 -32
- package/dist/index.js +45 -19
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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.
|
|
569
|
+
* null) from an Astralform older than 0.69.46.
|
|
570
570
|
*/
|
|
571
571
|
repository?: string | null;
|
|
572
572
|
}
|
|
@@ -619,15 +619,30 @@ interface AgentInfo {
|
|
|
619
619
|
isEnabled: boolean;
|
|
620
620
|
avatarUrl?: string;
|
|
621
621
|
/**
|
|
622
|
-
*
|
|
623
|
-
*
|
|
624
|
-
*
|
|
622
|
+
* Whether this agent's tasks can name a repository — the workspace has GitHub
|
|
623
|
+
* connected and enabled here. A client shows Projects and Tasks on it.
|
|
624
|
+
*
|
|
625
|
+
* Derived by the server from the connector, so it cannot go stale the way the
|
|
626
|
+
* retired `mode` toggle could. It gates a SURFACE, not an ability: naming a
|
|
627
|
+
* repository is optional on every task, and a task that names none is an
|
|
628
|
+
* ordinary chat. Absent on Astralform older than 0.69.50 — fall back to `mode`
|
|
629
|
+
* there.
|
|
625
630
|
*
|
|
626
631
|
* It is a property of the WORKSPACE, not of a persona: `GET /v1/agents` selects
|
|
627
|
-
* the workspace row itself and returns exactly one entry, so
|
|
628
|
-
* `agents[0].
|
|
629
|
-
*
|
|
630
|
-
|
|
632
|
+
* the workspace row itself and returns exactly one entry, so read
|
|
633
|
+
* `agents[0].codeProjectsEnabled`. The workspace picker (`listAgents`) does not
|
|
634
|
+
* carry it, so a client learns this after opening an agent.
|
|
635
|
+
*/
|
|
636
|
+
codeProjectsEnabled?: boolean;
|
|
637
|
+
/**
|
|
638
|
+
* @deprecated Removed in the next Astralform release. There is no agent mode —
|
|
639
|
+
* a repository belongs to the TASK, so one agent answers general questions and
|
|
640
|
+
* works in repositories from the same list. Read {@link codeProjectsEnabled}.
|
|
641
|
+
*
|
|
642
|
+
* Still reported for one release, as the STORED value of the retired column, so
|
|
643
|
+
* clients built before the change keep behaving exactly as they did. Do not
|
|
644
|
+
* treat it as an alias for `codeProjectsEnabled`: an agent that never had the
|
|
645
|
+
* toggle set still reports `"chat"` while its tasks can bind perfectly well.
|
|
631
646
|
*/
|
|
632
647
|
mode?: "chat" | "code";
|
|
633
648
|
}
|
|
@@ -759,12 +774,13 @@ interface ChatStreamRequest {
|
|
|
759
774
|
/**
|
|
760
775
|
* Which project (GitHub repository, `owner/repo`) this task belongs to.
|
|
761
776
|
*
|
|
762
|
-
*
|
|
763
|
-
*
|
|
764
|
-
*
|
|
765
|
-
*
|
|
766
|
-
*
|
|
767
|
-
*
|
|
777
|
+
* Optional on every agent. The first turn that names one binds the task, and a
|
|
778
|
+
* later turn may omit it or repeat the same value; a DIFFERENT value is refused
|
|
779
|
+
* (409), not ignored — a task is bound to one repository for life, so a
|
|
780
|
+
* different repository means a new task. A task that never names one is an
|
|
781
|
+
* ordinary chat; since Astralform 0.69.50 there is no agent mode that requires
|
|
782
|
+
* one.
|
|
783
|
+
* Astralform >= 0.69.46.
|
|
768
784
|
*/
|
|
769
785
|
repository?: string;
|
|
770
786
|
mcp_manifest?: ToolDefinition[];
|
|
@@ -791,7 +807,7 @@ interface ChatStreamRequest {
|
|
|
791
807
|
reasoning_effort?: ReasoningEffort;
|
|
792
808
|
temperature?: number;
|
|
793
809
|
}
|
|
794
|
-
/** One repository an app user works with on
|
|
810
|
+
/** One repository an app user works with on an agent. */
|
|
795
811
|
interface CodeProject {
|
|
796
812
|
repoFullName: string;
|
|
797
813
|
addedAt: string;
|
|
@@ -1064,13 +1080,13 @@ interface SendOptions$1 extends ModelChoiceOptions {
|
|
|
1064
1080
|
*/
|
|
1065
1081
|
goal?: string;
|
|
1066
1082
|
/**
|
|
1067
|
-
* The project this task belongs to (`owner/repo`),
|
|
1083
|
+
* The project this task belongs to (`owner/repo`), when it has one.
|
|
1068
1084
|
*
|
|
1069
1085
|
* Send it on the turn that STARTS a task; the binding is write-once, so a
|
|
1070
1086
|
* later turn may omit it or repeat the same value, and a DIFFERENT value is
|
|
1071
|
-
* refused (409) rather than ignored.
|
|
1072
|
-
*
|
|
1073
|
-
*
|
|
1087
|
+
* refused (409) rather than ignored. Omit it entirely and the task is an
|
|
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.
|
|
1074
1090
|
*/
|
|
1075
1091
|
repository?: string;
|
|
1076
1092
|
}
|
|
@@ -1223,9 +1239,10 @@ declare class AstralformClient {
|
|
|
1223
1239
|
/**
|
|
1224
1240
|
* A page of conversations, newest-updated first.
|
|
1225
1241
|
*
|
|
1226
|
-
* `options.repository` narrows to one project's tasks (`owner/repo`)
|
|
1227
|
-
*
|
|
1228
|
-
*
|
|
1242
|
+
* `options.repository` narrows to one project's tasks (`owner/repo`) — the same
|
|
1243
|
+
* paging applies within the filter, so a client showing tasks per project pages
|
|
1244
|
+
* each project separately. Tasks that named no repository fall outside every
|
|
1245
|
+
* such filter; list them with no filter at all.
|
|
1229
1246
|
*/
|
|
1230
1247
|
getConversations(limit?: number, offset?: number, options?: {
|
|
1231
1248
|
repository?: string;
|
|
@@ -1318,10 +1335,11 @@ declare class AstralformClient {
|
|
|
1318
1335
|
* The projects (GitHub repositories) this app user works with, and what they
|
|
1319
1336
|
* may add.
|
|
1320
1337
|
*
|
|
1321
|
-
* A project list is per app user
|
|
1322
|
-
*
|
|
1323
|
-
*
|
|
1324
|
-
*
|
|
1338
|
+
* A project list is per app user: the developer connects the workspace's GitHub
|
|
1339
|
+
* account, and each user curates their own list from what that connection
|
|
1340
|
+
* covers. There is no agent-level gate — an agent with no GitHub lists nothing,
|
|
1341
|
+
* reports `not_installed` from `available()`, and refuses `add()`. Read
|
|
1342
|
+
* {@link AgentInfo.codeProjectsEnabled} to decide whether to show the surface.
|
|
1325
1343
|
*/
|
|
1326
1344
|
readonly code: {
|
|
1327
1345
|
projects: {
|
|
@@ -1820,14 +1838,15 @@ interface SendOptions extends ModelChoiceOptions {
|
|
|
1820
1838
|
*/
|
|
1821
1839
|
goal?: string;
|
|
1822
1840
|
/**
|
|
1823
|
-
* The project this task belongs to (`owner/repo`),
|
|
1841
|
+
* The project this task belongs to (`owner/repo`), when it has one.
|
|
1824
1842
|
*
|
|
1825
1843
|
* Write-once server-side, and the refusal is the part that matters: the FIRST
|
|
1826
|
-
* turn binds the task, a later turn may omit it or
|
|
1827
|
-
* a DIFFERENT value is refused (409) rather than
|
|
1828
|
-
* the wrong repository is the failure that rule
|
|
1829
|
-
*
|
|
1830
|
-
*
|
|
1844
|
+
* turn that names a repository binds the task, a later turn may omit it or
|
|
1845
|
+
* repeat the same value, and a DIFFERENT value is refused (409) rather than
|
|
1846
|
+
* ignored — silently acting on the wrong repository is the failure that rule
|
|
1847
|
+
* exists to prevent. Omit it entirely and the task is an ordinary chat: since
|
|
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.
|
|
1831
1850
|
*/
|
|
1832
1851
|
repository?: string;
|
|
1833
1852
|
}
|
|
@@ -1999,6 +2018,14 @@ declare class StreamManager {
|
|
|
1999
2018
|
*/
|
|
2000
2019
|
private settleIdle;
|
|
2001
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;
|
|
2002
2029
|
private restore;
|
|
2003
2030
|
/**
|
|
2004
2031
|
* Has a live turn taken the block view over?
|
|
@@ -2037,6 +2064,12 @@ declare class StreamManager {
|
|
|
2037
2064
|
* that started it, which is emitted as a bubble with no events — the whole
|
|
2038
2065
|
* reason a conversation reopened mid-turn now shows the message that started
|
|
2039
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.
|
|
2040
2073
|
*/
|
|
2041
2074
|
private replayHistory;
|
|
2042
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.
|
|
569
|
+
* null) from an Astralform older than 0.69.46.
|
|
570
570
|
*/
|
|
571
571
|
repository?: string | null;
|
|
572
572
|
}
|
|
@@ -619,15 +619,30 @@ interface AgentInfo {
|
|
|
619
619
|
isEnabled: boolean;
|
|
620
620
|
avatarUrl?: string;
|
|
621
621
|
/**
|
|
622
|
-
*
|
|
623
|
-
*
|
|
624
|
-
*
|
|
622
|
+
* Whether this agent's tasks can name a repository — the workspace has GitHub
|
|
623
|
+
* connected and enabled here. A client shows Projects and Tasks on it.
|
|
624
|
+
*
|
|
625
|
+
* Derived by the server from the connector, so it cannot go stale the way the
|
|
626
|
+
* retired `mode` toggle could. It gates a SURFACE, not an ability: naming a
|
|
627
|
+
* repository is optional on every task, and a task that names none is an
|
|
628
|
+
* ordinary chat. Absent on Astralform older than 0.69.50 — fall back to `mode`
|
|
629
|
+
* there.
|
|
625
630
|
*
|
|
626
631
|
* It is a property of the WORKSPACE, not of a persona: `GET /v1/agents` selects
|
|
627
|
-
* the workspace row itself and returns exactly one entry, so
|
|
628
|
-
* `agents[0].
|
|
629
|
-
*
|
|
630
|
-
|
|
632
|
+
* the workspace row itself and returns exactly one entry, so read
|
|
633
|
+
* `agents[0].codeProjectsEnabled`. The workspace picker (`listAgents`) does not
|
|
634
|
+
* carry it, so a client learns this after opening an agent.
|
|
635
|
+
*/
|
|
636
|
+
codeProjectsEnabled?: boolean;
|
|
637
|
+
/**
|
|
638
|
+
* @deprecated Removed in the next Astralform release. There is no agent mode —
|
|
639
|
+
* a repository belongs to the TASK, so one agent answers general questions and
|
|
640
|
+
* works in repositories from the same list. Read {@link codeProjectsEnabled}.
|
|
641
|
+
*
|
|
642
|
+
* Still reported for one release, as the STORED value of the retired column, so
|
|
643
|
+
* clients built before the change keep behaving exactly as they did. Do not
|
|
644
|
+
* treat it as an alias for `codeProjectsEnabled`: an agent that never had the
|
|
645
|
+
* toggle set still reports `"chat"` while its tasks can bind perfectly well.
|
|
631
646
|
*/
|
|
632
647
|
mode?: "chat" | "code";
|
|
633
648
|
}
|
|
@@ -759,12 +774,13 @@ interface ChatStreamRequest {
|
|
|
759
774
|
/**
|
|
760
775
|
* Which project (GitHub repository, `owner/repo`) this task belongs to.
|
|
761
776
|
*
|
|
762
|
-
*
|
|
763
|
-
*
|
|
764
|
-
*
|
|
765
|
-
*
|
|
766
|
-
*
|
|
767
|
-
*
|
|
777
|
+
* Optional on every agent. The first turn that names one binds the task, and a
|
|
778
|
+
* later turn may omit it or repeat the same value; a DIFFERENT value is refused
|
|
779
|
+
* (409), not ignored — a task is bound to one repository for life, so a
|
|
780
|
+
* different repository means a new task. A task that never names one is an
|
|
781
|
+
* ordinary chat; since Astralform 0.69.50 there is no agent mode that requires
|
|
782
|
+
* one.
|
|
783
|
+
* Astralform >= 0.69.46.
|
|
768
784
|
*/
|
|
769
785
|
repository?: string;
|
|
770
786
|
mcp_manifest?: ToolDefinition[];
|
|
@@ -791,7 +807,7 @@ interface ChatStreamRequest {
|
|
|
791
807
|
reasoning_effort?: ReasoningEffort;
|
|
792
808
|
temperature?: number;
|
|
793
809
|
}
|
|
794
|
-
/** One repository an app user works with on
|
|
810
|
+
/** One repository an app user works with on an agent. */
|
|
795
811
|
interface CodeProject {
|
|
796
812
|
repoFullName: string;
|
|
797
813
|
addedAt: string;
|
|
@@ -1064,13 +1080,13 @@ interface SendOptions$1 extends ModelChoiceOptions {
|
|
|
1064
1080
|
*/
|
|
1065
1081
|
goal?: string;
|
|
1066
1082
|
/**
|
|
1067
|
-
* The project this task belongs to (`owner/repo`),
|
|
1083
|
+
* The project this task belongs to (`owner/repo`), when it has one.
|
|
1068
1084
|
*
|
|
1069
1085
|
* Send it on the turn that STARTS a task; the binding is write-once, so a
|
|
1070
1086
|
* later turn may omit it or repeat the same value, and a DIFFERENT value is
|
|
1071
|
-
* refused (409) rather than ignored.
|
|
1072
|
-
*
|
|
1073
|
-
*
|
|
1087
|
+
* refused (409) rather than ignored. Omit it entirely and the task is an
|
|
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.
|
|
1074
1090
|
*/
|
|
1075
1091
|
repository?: string;
|
|
1076
1092
|
}
|
|
@@ -1223,9 +1239,10 @@ declare class AstralformClient {
|
|
|
1223
1239
|
/**
|
|
1224
1240
|
* A page of conversations, newest-updated first.
|
|
1225
1241
|
*
|
|
1226
|
-
* `options.repository` narrows to one project's tasks (`owner/repo`)
|
|
1227
|
-
*
|
|
1228
|
-
*
|
|
1242
|
+
* `options.repository` narrows to one project's tasks (`owner/repo`) — the same
|
|
1243
|
+
* paging applies within the filter, so a client showing tasks per project pages
|
|
1244
|
+
* each project separately. Tasks that named no repository fall outside every
|
|
1245
|
+
* such filter; list them with no filter at all.
|
|
1229
1246
|
*/
|
|
1230
1247
|
getConversations(limit?: number, offset?: number, options?: {
|
|
1231
1248
|
repository?: string;
|
|
@@ -1318,10 +1335,11 @@ declare class AstralformClient {
|
|
|
1318
1335
|
* The projects (GitHub repositories) this app user works with, and what they
|
|
1319
1336
|
* may add.
|
|
1320
1337
|
*
|
|
1321
|
-
* A project list is per app user
|
|
1322
|
-
*
|
|
1323
|
-
*
|
|
1324
|
-
*
|
|
1338
|
+
* A project list is per app user: the developer connects the workspace's GitHub
|
|
1339
|
+
* account, and each user curates their own list from what that connection
|
|
1340
|
+
* covers. There is no agent-level gate — an agent with no GitHub lists nothing,
|
|
1341
|
+
* reports `not_installed` from `available()`, and refuses `add()`. Read
|
|
1342
|
+
* {@link AgentInfo.codeProjectsEnabled} to decide whether to show the surface.
|
|
1325
1343
|
*/
|
|
1326
1344
|
readonly code: {
|
|
1327
1345
|
projects: {
|
|
@@ -1820,14 +1838,15 @@ interface SendOptions extends ModelChoiceOptions {
|
|
|
1820
1838
|
*/
|
|
1821
1839
|
goal?: string;
|
|
1822
1840
|
/**
|
|
1823
|
-
* The project this task belongs to (`owner/repo`),
|
|
1841
|
+
* The project this task belongs to (`owner/repo`), when it has one.
|
|
1824
1842
|
*
|
|
1825
1843
|
* Write-once server-side, and the refusal is the part that matters: the FIRST
|
|
1826
|
-
* turn binds the task, a later turn may omit it or
|
|
1827
|
-
* a DIFFERENT value is refused (409) rather than
|
|
1828
|
-
* the wrong repository is the failure that rule
|
|
1829
|
-
*
|
|
1830
|
-
*
|
|
1844
|
+
* turn that names a repository binds the task, a later turn may omit it or
|
|
1845
|
+
* repeat the same value, and a DIFFERENT value is refused (409) rather than
|
|
1846
|
+
* ignored — silently acting on the wrong repository is the failure that rule
|
|
1847
|
+
* exists to prevent. Omit it entirely and the task is an ordinary chat: since
|
|
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.
|
|
1831
1850
|
*/
|
|
1832
1851
|
repository?: string;
|
|
1833
1852
|
}
|
|
@@ -1999,6 +2018,14 @@ declare class StreamManager {
|
|
|
1999
2018
|
*/
|
|
2000
2019
|
private settleIdle;
|
|
2001
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;
|
|
2002
2029
|
private restore;
|
|
2003
2030
|
/**
|
|
2004
2031
|
* Has a live turn taken the block view over?
|
|
@@ -2037,6 +2064,12 @@ declare class StreamManager {
|
|
|
2037
2064
|
* that started it, which is emitted as a bubble with no events — the whole
|
|
2038
2065
|
* reason a conversation reopened mid-turn now shows the message that started
|
|
2039
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.
|
|
2040
2073
|
*/
|
|
2041
2074
|
private replayHistory;
|
|
2042
2075
|
private setActiveConversation;
|
package/dist/index.js
CHANGED
|
@@ -338,15 +338,16 @@ function isApiKeyConfig(config) {
|
|
|
338
338
|
}
|
|
339
339
|
var AstralformClient = class {
|
|
340
340
|
constructor(config) {
|
|
341
|
-
// ---
|
|
341
|
+
// --- Projects: the repositories this app user works with ---
|
|
342
342
|
/**
|
|
343
343
|
* The projects (GitHub repositories) this app user works with, and what they
|
|
344
344
|
* may add.
|
|
345
345
|
*
|
|
346
|
-
* A project list is per app user
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
346
|
+
* A project list is per app user: the developer connects the workspace's GitHub
|
|
347
|
+
* account, and each user curates their own list from what that connection
|
|
348
|
+
* covers. There is no agent-level gate — an agent with no GitHub lists nothing,
|
|
349
|
+
* reports `not_installed` from `available()`, and refuses `add()`. Read
|
|
350
|
+
* {@link AgentInfo.codeProjectsEnabled} to decide whether to show the surface.
|
|
350
351
|
*/
|
|
351
352
|
this.code = {
|
|
352
353
|
projects: {
|
|
@@ -644,9 +645,10 @@ var AstralformClient = class {
|
|
|
644
645
|
/**
|
|
645
646
|
* A page of conversations, newest-updated first.
|
|
646
647
|
*
|
|
647
|
-
* `options.repository` narrows to one project's tasks (`owner/repo`)
|
|
648
|
-
*
|
|
649
|
-
*
|
|
648
|
+
* `options.repository` narrows to one project's tasks (`owner/repo`) — the same
|
|
649
|
+
* paging applies within the filter, so a client showing tasks per project pages
|
|
650
|
+
* each project separately. Tasks that named no repository fall outside every
|
|
651
|
+
* such filter; list them with no filter at all.
|
|
650
652
|
*/
|
|
651
653
|
async getConversations(limit = 50, offset = 0, options) {
|
|
652
654
|
const safeLimit = Math.max(1, Math.min(200, Math.floor(Number(limit))));
|
|
@@ -1747,7 +1749,7 @@ var ChatSession = class {
|
|
|
1747
1749
|
image_mode: options?.imageMode,
|
|
1748
1750
|
video_mode: options?.videoMode,
|
|
1749
1751
|
goal: options?.goal,
|
|
1750
|
-
// The project this task belongs to,
|
|
1752
|
+
// The project this task belongs to, when it has one. Write-once
|
|
1751
1753
|
// server-side: sent on every turn, honoured on the first.
|
|
1752
1754
|
repository: options?.repository,
|
|
1753
1755
|
// Per-request model choice (client-side model selection).
|
|
@@ -2885,23 +2887,41 @@ var StreamManager = class {
|
|
|
2885
2887
|
}
|
|
2886
2888
|
}
|
|
2887
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
|
+
}
|
|
2888
2902
|
async restore(conversationId, gen) {
|
|
2889
2903
|
const superseded = () => gen !== this.generation;
|
|
2890
2904
|
if (superseded()) return;
|
|
2891
2905
|
const turn = this.turnCounter;
|
|
2892
2906
|
const announcedRestoring = !this.session.isStreaming;
|
|
2893
2907
|
if (announcedRestoring) this.setState("restoring");
|
|
2894
|
-
let activeJobId = null;
|
|
2895
|
-
try {
|
|
2896
|
-
const res = await this.session.client.getActiveJob(conversationId);
|
|
2897
|
-
activeJobId = res.jobId;
|
|
2898
|
-
} catch {
|
|
2899
|
-
}
|
|
2900
2908
|
if (superseded()) return;
|
|
2901
|
-
|
|
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;
|
|
2902
2916
|
if (superseded()) return;
|
|
2903
2917
|
if (announcedRestoring && this.viewTakenOverByLiveTurn()) return;
|
|
2904
|
-
if (
|
|
2918
|
+
if (jobsRequest && !await this.replayHistory(
|
|
2919
|
+
conversationId,
|
|
2920
|
+
gen,
|
|
2921
|
+
activeJobId,
|
|
2922
|
+
turn,
|
|
2923
|
+
jobsRequest
|
|
2924
|
+
))
|
|
2905
2925
|
return;
|
|
2906
2926
|
if (activeJobId) {
|
|
2907
2927
|
this.setState("streaming");
|
|
@@ -2959,11 +2979,17 @@ var StreamManager = class {
|
|
|
2959
2979
|
* that started it, which is emitted as a bubble with no events — the whole
|
|
2960
2980
|
* reason a conversation reopened mid-turn now shows the message that started
|
|
2961
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.
|
|
2962
2988
|
*/
|
|
2963
|
-
async replayHistory(conversationId, gen, activeJobId, turn) {
|
|
2989
|
+
async replayHistory(conversationId, gen, activeJobId, turn, jobsRequest) {
|
|
2964
2990
|
const stopReplay = () => gen !== this.generation || this.viewTakenOverByLiveTurn() || this.turnStarted(turn);
|
|
2965
2991
|
try {
|
|
2966
|
-
const jobs = await
|
|
2992
|
+
const jobs = await jobsRequest;
|
|
2967
2993
|
if (stopReplay()) return false;
|
|
2968
2994
|
const replayableJobs = jobs.filter(
|
|
2969
2995
|
(j) => j.job_id !== activeJobId
|