@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.cjs
CHANGED
|
@@ -389,15 +389,16 @@ function isApiKeyConfig(config) {
|
|
|
389
389
|
}
|
|
390
390
|
var AstralformClient = class {
|
|
391
391
|
constructor(config) {
|
|
392
|
-
// ---
|
|
392
|
+
// --- Projects: the repositories this app user works with ---
|
|
393
393
|
/**
|
|
394
394
|
* The projects (GitHub repositories) this app user works with, and what they
|
|
395
395
|
* may add.
|
|
396
396
|
*
|
|
397
|
-
* A project list is per app user
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
*
|
|
397
|
+
* A project list is per app user: the developer connects the workspace's GitHub
|
|
398
|
+
* account, and each user curates their own list from what that connection
|
|
399
|
+
* covers. There is no agent-level gate — an agent with no GitHub lists nothing,
|
|
400
|
+
* reports `not_installed` from `available()`, and refuses `add()`. Read
|
|
401
|
+
* {@link AgentInfo.codeProjectsEnabled} to decide whether to show the surface.
|
|
401
402
|
*/
|
|
402
403
|
this.code = {
|
|
403
404
|
projects: {
|
|
@@ -695,9 +696,10 @@ var AstralformClient = class {
|
|
|
695
696
|
/**
|
|
696
697
|
* A page of conversations, newest-updated first.
|
|
697
698
|
*
|
|
698
|
-
* `options.repository` narrows to one project's tasks (`owner/repo`)
|
|
699
|
-
*
|
|
700
|
-
*
|
|
699
|
+
* `options.repository` narrows to one project's tasks (`owner/repo`) — the same
|
|
700
|
+
* paging applies within the filter, so a client showing tasks per project pages
|
|
701
|
+
* each project separately. Tasks that named no repository fall outside every
|
|
702
|
+
* such filter; list them with no filter at all.
|
|
701
703
|
*/
|
|
702
704
|
async getConversations(limit = 50, offset = 0, options) {
|
|
703
705
|
const safeLimit = Math.max(1, Math.min(200, Math.floor(Number(limit))));
|
|
@@ -1798,7 +1800,7 @@ var ChatSession = class {
|
|
|
1798
1800
|
image_mode: options?.imageMode,
|
|
1799
1801
|
video_mode: options?.videoMode,
|
|
1800
1802
|
goal: options?.goal,
|
|
1801
|
-
// The project this task belongs to,
|
|
1803
|
+
// The project this task belongs to, when it has one. Write-once
|
|
1802
1804
|
// server-side: sent on every turn, honoured on the first.
|
|
1803
1805
|
repository: options?.repository,
|
|
1804
1806
|
// Per-request model choice (client-side model selection).
|
|
@@ -2936,23 +2938,41 @@ var StreamManager = class {
|
|
|
2936
2938
|
}
|
|
2937
2939
|
}
|
|
2938
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
|
+
}
|
|
2939
2953
|
async restore(conversationId, gen) {
|
|
2940
2954
|
const superseded = () => gen !== this.generation;
|
|
2941
2955
|
if (superseded()) return;
|
|
2942
2956
|
const turn = this.turnCounter;
|
|
2943
2957
|
const announcedRestoring = !this.session.isStreaming;
|
|
2944
2958
|
if (announcedRestoring) this.setState("restoring");
|
|
2945
|
-
let activeJobId = null;
|
|
2946
|
-
try {
|
|
2947
|
-
const res = await this.session.client.getActiveJob(conversationId);
|
|
2948
|
-
activeJobId = res.jobId;
|
|
2949
|
-
} catch {
|
|
2950
|
-
}
|
|
2951
2959
|
if (superseded()) return;
|
|
2952
|
-
|
|
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;
|
|
2953
2967
|
if (superseded()) return;
|
|
2954
2968
|
if (announcedRestoring && this.viewTakenOverByLiveTurn()) return;
|
|
2955
|
-
if (
|
|
2969
|
+
if (jobsRequest && !await this.replayHistory(
|
|
2970
|
+
conversationId,
|
|
2971
|
+
gen,
|
|
2972
|
+
activeJobId,
|
|
2973
|
+
turn,
|
|
2974
|
+
jobsRequest
|
|
2975
|
+
))
|
|
2956
2976
|
return;
|
|
2957
2977
|
if (activeJobId) {
|
|
2958
2978
|
this.setState("streaming");
|
|
@@ -3010,11 +3030,17 @@ var StreamManager = class {
|
|
|
3010
3030
|
* that started it, which is emitted as a bubble with no events — the whole
|
|
3011
3031
|
* reason a conversation reopened mid-turn now shows the message that started
|
|
3012
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.
|
|
3013
3039
|
*/
|
|
3014
|
-
async replayHistory(conversationId, gen, activeJobId, turn) {
|
|
3040
|
+
async replayHistory(conversationId, gen, activeJobId, turn, jobsRequest) {
|
|
3015
3041
|
const stopReplay = () => gen !== this.generation || this.viewTakenOverByLiveTurn() || this.turnStarted(turn);
|
|
3016
3042
|
try {
|
|
3017
|
-
const jobs = await
|
|
3043
|
+
const jobs = await jobsRequest;
|
|
3018
3044
|
if (stopReplay()) return false;
|
|
3019
3045
|
const replayableJobs = jobs.filter(
|
|
3020
3046
|
(j) => j.job_id !== activeJobId
|