@superblocksteam/vite-plugin-file-sync 2.0.130-next.4 → 2.0.130-next.6
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/ai-service/agent/tools/apis/test-api.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/apis/test-api.js +1 -0
- package/dist/ai-service/agent/tools/apis/test-api.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/execute-request.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/integrations/execute-request.js +1 -0
- package/dist/ai-service/agent/tools/integrations/execute-request.js.map +1 -1
- package/dist/ai-service/app-interface/filesystem/virtual-file-system.d.ts.map +1 -1
- package/dist/ai-service/app-interface/filesystem/virtual-file-system.js +5 -3
- package/dist/ai-service/app-interface/filesystem/virtual-file-system.js.map +1 -1
- package/dist/ai-service/app-interface/shell.d.ts +0 -36
- package/dist/ai-service/app-interface/shell.d.ts.map +1 -1
- package/dist/ai-service/app-interface/shell.js +4 -169
- package/dist/ai-service/app-interface/shell.js.map +1 -1
- package/dist/ai-service/index.d.ts +38 -4
- package/dist/ai-service/index.d.ts.map +1 -1
- package/dist/ai-service/index.js +168 -12
- package/dist/ai-service/index.js.map +1 -1
- package/dist/ai-service/migration-auto-dispatch-readiness.d.ts +18 -0
- package/dist/ai-service/migration-auto-dispatch-readiness.d.ts.map +1 -0
- package/dist/ai-service/migration-auto-dispatch-readiness.js +17 -0
- package/dist/ai-service/migration-auto-dispatch-readiness.js.map +1 -0
- package/dist/ai-service/migration-llm-config.d.ts +7 -0
- package/dist/ai-service/migration-llm-config.d.ts.map +1 -0
- package/dist/ai-service/migration-llm-config.js +122 -0
- package/dist/ai-service/migration-llm-config.js.map +1 -0
- package/dist/ai-service/resolve-generation-state-for-ui.d.ts +8 -0
- package/dist/ai-service/resolve-generation-state-for-ui.d.ts.map +1 -0
- package/dist/ai-service/resolve-generation-state-for-ui.js +36 -0
- package/dist/ai-service/resolve-generation-state-for-ui.js.map +1 -0
- package/dist/ai-service/types.d.ts +6 -0
- package/dist/ai-service/types.d.ts.map +1 -1
- package/dist/ai-service/types.js.map +1 -1
- package/dist/ai-service/util/inference-jwt.d.ts +15 -0
- package/dist/ai-service/util/inference-jwt.d.ts.map +1 -0
- package/dist/ai-service/util/inference-jwt.js +56 -0
- package/dist/ai-service/util/inference-jwt.js.map +1 -0
- package/dist/file-system-helpers.d.ts +0 -13
- package/dist/file-system-helpers.d.ts.map +1 -1
- package/dist/file-system-helpers.js +1 -22
- package/dist/file-system-helpers.js.map +1 -1
- package/dist/migration/migration-verification.d.ts.map +1 -1
- package/dist/migration/migration-verification.js +1 -0
- package/dist/migration/migration-verification.js.map +1 -1
- package/dist/migration/translation-prompt.d.ts +7 -6
- package/dist/migration/translation-prompt.d.ts.map +1 -1
- package/dist/migration/translation-prompt.js +7 -6
- package/dist/migration/translation-prompt.js.map +1 -1
- package/dist/socket-manager.d.ts.map +1 -1
- package/dist/socket-manager.js +6 -0
- package/dist/socket-manager.js.map +1 -1
- package/dist/sync-service/list-dir.d.ts +1 -1
- package/dist/sync-service/list-dir.js +3 -3
- package/dist/sync-service/list-dir.js.map +1 -1
- package/package.json +9 -8
package/dist/ai-service/index.js
CHANGED
|
@@ -32,7 +32,7 @@ import { AppSkillsManager } from "./app-skills/manager.js";
|
|
|
32
32
|
import { isUploadedAttachment, toUploadedAttachmentContentPart, } from "./attachments/uploaded-content-part.js";
|
|
33
33
|
import { ChatSessionStore } from "./chat/chat-session-store.js";
|
|
34
34
|
import { normalizeTextAttachmentForModel } from "./chat/utils.js";
|
|
35
|
-
import { API_MIGRATION_ORIGINS, readPersistedChecklist, updateChecklistItem, } from "./checklist/persisted-checklist-store.js";
|
|
35
|
+
import { API_MIGRATION_ORIGINS, isApiMigrationOrigin, readPersistedChecklist, updateChecklistItem, } from "./checklist/persisted-checklist-store.js";
|
|
36
36
|
import { downloadContextFromBucketeer, downloadLatestContextFromBucketeer, restoreContextFromCheckpoint, } from "./context-download.js";
|
|
37
37
|
import { uploadContextToBucketeer } from "./context-upload.js";
|
|
38
38
|
import { AppContextStore } from "./context/app-context.js";
|
|
@@ -55,6 +55,8 @@ import { traceLLM } from "./llmobs/helpers.js";
|
|
|
55
55
|
import { getJwtTraceTags } from "./llmobs/helpers.js";
|
|
56
56
|
import llmobs from "./llmobs/index.js";
|
|
57
57
|
import { PlaywrightMcpServerManager } from "./mcp/playwright-server.js";
|
|
58
|
+
import { evaluateMigrationAutoDispatchReadiness } from "./migration-auto-dispatch-readiness.js";
|
|
59
|
+
import { buildServerMigrationLlmConfig } from "./migration-llm-config.js";
|
|
58
60
|
import { policyGateStreamPartToAgentStep } from "./policy-gate-step.js";
|
|
59
61
|
import { ClarkProfiler } from "./profiler/clark-profiler.js";
|
|
60
62
|
import { explainEventHandlerCodePrompt } from "./prompts/explain-code.js";
|
|
@@ -62,6 +64,7 @@ import { buildSummarizeApiUsagePrompt } from "./prompts/summarize-api-usage.js";
|
|
|
62
64
|
import { checkAiQuota } from "./quota-client.js";
|
|
63
65
|
import { RecordingManager, createRecordingFetch } from "./recording/index.js";
|
|
64
66
|
import { RequestDeduplicator } from "./request-deduplicator.js";
|
|
67
|
+
import { resolveGenerationStateForUi } from "./resolve-generation-state-for-ui.js";
|
|
65
68
|
import { scanContentForSecrets } from "./security/secret-scanner-service.js";
|
|
66
69
|
import { SecretRedactor } from "./security/secret-scanner.js";
|
|
67
70
|
import { ClarkStateNames, Clark, SERVICE_STARTED_WITH_DRAFT, USER_ACCEPTED_DRAFT, USER_REJECTED_DRAFT, USER_SENT_PROMPT, USER_CANCELED, AGENT_CANCELED, } from "./state-machine/clark-fsm.js";
|
|
@@ -80,6 +83,7 @@ import { catchBackgroundPeerDisconnect, StablePeer, } from "./state-machine/help
|
|
|
80
83
|
import { transitionFrom } from "./state-machine/helpers/transition.js";
|
|
81
84
|
import { isTaskAccessibleTo, registerBackgroundTaskTypes, resyncActiveTaskStatusesToPeer, TaskStore, wireTaskStatusPushToPeer, } from "./tasks/index.js";
|
|
82
85
|
import { TemplateRenderer } from "./template-renderer.js";
|
|
86
|
+
import { describeMigrationInferenceJwt, isUsableMigrationInferenceJwt, } from "./util/inference-jwt.js";
|
|
83
87
|
import { createJsonStreamParser } from "./util/json-stream-parser.js";
|
|
84
88
|
import { processLLMConfig } from "./util/llm-config-utils.js";
|
|
85
89
|
import { parseJwt } from "./util/parse-jwt.js";
|
|
@@ -359,6 +363,9 @@ export class AiService extends TracedEventEmitter {
|
|
|
359
363
|
try {
|
|
360
364
|
this.tokenManagerJwt = event.token;
|
|
361
365
|
this.getLogger().info(`[ai-service] token updated via tokenManager`);
|
|
366
|
+
if (event.token && isUsableMigrationInferenceJwt(event.token)) {
|
|
367
|
+
this.updateClarkJwt(event.token);
|
|
368
|
+
}
|
|
362
369
|
}
|
|
363
370
|
catch (err) {
|
|
364
371
|
console.error("[ai-service] tokenUpdated listener threw", err);
|
|
@@ -458,9 +465,16 @@ export class AiService extends TracedEventEmitter {
|
|
|
458
465
|
* Updates the JWT in Clark context
|
|
459
466
|
*/
|
|
460
467
|
updateClarkJwt(jwt) {
|
|
461
|
-
|
|
462
|
-
|
|
468
|
+
const jwtDetails = describeMigrationInferenceJwt(jwt);
|
|
469
|
+
if (!jwt || !jwtDetails.usable) {
|
|
470
|
+
return;
|
|
463
471
|
}
|
|
472
|
+
this.clark.updateContext({ jwt });
|
|
473
|
+
const llmConfig = this.lastMigrationTurnCredentials?.llmConfig ??
|
|
474
|
+
this.clark.context.llmConfig ??
|
|
475
|
+
buildServerMigrationLlmConfig(this.config.flagBootstrap);
|
|
476
|
+
this.storeMigrationTurnCredentials(jwt, llmConfig);
|
|
477
|
+
this.tryAutoDispatchMigrationTurnIfReady();
|
|
464
478
|
}
|
|
465
479
|
// ===== Recording API =====
|
|
466
480
|
/**
|
|
@@ -878,7 +892,7 @@ export class AiService extends TracedEventEmitter {
|
|
|
878
892
|
}
|
|
879
893
|
// Reset stale in_progress items to pending. After a dev-server restart,
|
|
880
894
|
// items left in_progress are not truly running — resetting them allows
|
|
881
|
-
// the UI polling trigger
|
|
895
|
+
// auto-dispatch and the UI polling trigger to re-dispatch Clark.
|
|
882
896
|
const staleInProgressItems = checklist.items.filter((item) => API_MIGRATION_ORIGINS.has(item.origin) && item.status === "in_progress");
|
|
883
897
|
for (const item of staleInProgressItems) {
|
|
884
898
|
await updateChecklistItem({
|
|
@@ -920,6 +934,130 @@ export class AiService extends TracedEventEmitter {
|
|
|
920
934
|
},
|
|
921
935
|
});
|
|
922
936
|
}
|
|
937
|
+
this.tryAutoDispatchMigrationTurnIfReady();
|
|
938
|
+
}
|
|
939
|
+
migrationAppArtifactsReady = false;
|
|
940
|
+
migrationAutoDispatchPending = false;
|
|
941
|
+
migrationAutoDispatchInFlight = false;
|
|
942
|
+
lastMigrationTurnCredentials;
|
|
943
|
+
hasInitialPendingMigrationWork(items) {
|
|
944
|
+
const pendingItems = items.filter((item) => isApiMigrationOrigin(item.origin) &&
|
|
945
|
+
(item.status === "pending" || item.status === "in_progress"));
|
|
946
|
+
if (pendingItems.length === 0) {
|
|
947
|
+
return false;
|
|
948
|
+
}
|
|
949
|
+
return !pendingItems.some((item) => item.lastFailureReason);
|
|
950
|
+
}
|
|
951
|
+
resolveMigrationTurnCredentials() {
|
|
952
|
+
const cachedJwt = this.lastMigrationTurnCredentials?.jwt;
|
|
953
|
+
const inferenceJwt = this.getInferenceJwt();
|
|
954
|
+
const jwt = (cachedJwt && isUsableMigrationInferenceJwt(cachedJwt)
|
|
955
|
+
? cachedJwt
|
|
956
|
+
: undefined) ??
|
|
957
|
+
(inferenceJwt && isUsableMigrationInferenceJwt(inferenceJwt)
|
|
958
|
+
? inferenceJwt
|
|
959
|
+
: undefined);
|
|
960
|
+
const llmConfig = this.lastMigrationTurnCredentials?.llmConfig ??
|
|
961
|
+
this.clark.context.llmConfig ??
|
|
962
|
+
buildServerMigrationLlmConfig(this.config.flagBootstrap);
|
|
963
|
+
return { jwt, llmConfig };
|
|
964
|
+
}
|
|
965
|
+
storeMigrationTurnCredentials(jwt, llmConfig) {
|
|
966
|
+
const nextJwt = jwt && jwt.length > 0 ? jwt : this.lastMigrationTurnCredentials?.jwt;
|
|
967
|
+
this.lastMigrationTurnCredentials = {
|
|
968
|
+
...(nextJwt ? { jwt: nextJwt } : {}),
|
|
969
|
+
llmConfig,
|
|
970
|
+
};
|
|
971
|
+
if (jwt && jwt.length > 0 && !this.getInferenceJwt()) {
|
|
972
|
+
this.clark.updateContext({ jwt });
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
isRetriableMigrationAutoDispatchFailure(reason) {
|
|
976
|
+
if (!reason) {
|
|
977
|
+
return false;
|
|
978
|
+
}
|
|
979
|
+
return (reason.startsWith("busy:") ||
|
|
980
|
+
reason === "pending-tool-permission" ||
|
|
981
|
+
reason === "awaiting-interactive-response");
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Called by dev startup once DBFS download (or upload-first local tree)
|
|
985
|
+
* has finished so migration scratch/checklist files are on disk.
|
|
986
|
+
*/
|
|
987
|
+
notifyMigrationAppArtifactsReady() {
|
|
988
|
+
if (this.migrationAppArtifactsReady) {
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
this.migrationAppArtifactsReady = true;
|
|
992
|
+
this.tryAutoDispatchMigrationTurnIfReady();
|
|
993
|
+
}
|
|
994
|
+
tryAutoDispatchMigrationTurnIfReady() {
|
|
995
|
+
if (this.migrationAutoDispatchInFlight) {
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
const { jwt } = this.resolveMigrationTurnCredentials();
|
|
999
|
+
const readiness = evaluateMigrationAutoDispatchReadiness({
|
|
1000
|
+
appArtifactsReady: this.migrationAppArtifactsReady,
|
|
1001
|
+
hasConnectedPeer: this.hasConnectedPeer(),
|
|
1002
|
+
hasUsableJwt: Boolean(jwt),
|
|
1003
|
+
});
|
|
1004
|
+
if (!readiness.ready) {
|
|
1005
|
+
if (readiness.reason === "jwt-unavailable") {
|
|
1006
|
+
this.migrationAutoDispatchPending = true;
|
|
1007
|
+
}
|
|
1008
|
+
return;
|
|
1009
|
+
}
|
|
1010
|
+
void this.maybeAutoDispatchMigrationTurn().catch((error) => {
|
|
1011
|
+
this.getLogger().error("[ai-service] Migration auto-dispatch failed", getErrorMeta(error));
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* Attempts to start the initial post-flip migration turn without UI
|
|
1016
|
+
* involvement. Skips user-initiated focused-debug retries (items with
|
|
1017
|
+
* `lastFailureReason`) and defers when JWT is unavailable.
|
|
1018
|
+
*/
|
|
1019
|
+
async maybeAutoDispatchMigrationTurn() {
|
|
1020
|
+
if (this.migrationAutoDispatchInFlight) {
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
this.migrationAutoDispatchInFlight = true;
|
|
1024
|
+
try {
|
|
1025
|
+
const checklist = await readPersistedChecklist(this.appRootDirPath);
|
|
1026
|
+
if (!checklist) {
|
|
1027
|
+
this.migrationAutoDispatchPending = false;
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
if (!this.hasInitialPendingMigrationWork(checklist.items)) {
|
|
1031
|
+
this.migrationAutoDispatchPending = false;
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
const { jwt, llmConfig } = this.resolveMigrationTurnCredentials();
|
|
1035
|
+
if (!jwt) {
|
|
1036
|
+
this.migrationAutoDispatchPending = true;
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
1039
|
+
const result = await this.handleAiTriggerMigrationTurn({
|
|
1040
|
+
jwt,
|
|
1041
|
+
llmConfig,
|
|
1042
|
+
triggeredBy: "auto-dispatch",
|
|
1043
|
+
});
|
|
1044
|
+
if (result.dispatched) {
|
|
1045
|
+
this.migrationAutoDispatchPending = false;
|
|
1046
|
+
this.getLogger().info("[ai-service] Auto-dispatched post-flip migration turn");
|
|
1047
|
+
}
|
|
1048
|
+
else if (result.reason === "already-triggered") {
|
|
1049
|
+
this.migrationAutoDispatchPending = false;
|
|
1050
|
+
}
|
|
1051
|
+
else if (this.isRetriableMigrationAutoDispatchFailure(result.reason)) {
|
|
1052
|
+
this.migrationAutoDispatchPending = true;
|
|
1053
|
+
}
|
|
1054
|
+
else {
|
|
1055
|
+
this.migrationAutoDispatchPending = false;
|
|
1056
|
+
}
|
|
1057
|
+
}
|
|
1058
|
+
finally {
|
|
1059
|
+
this.migrationAutoDispatchInFlight = false;
|
|
1060
|
+
}
|
|
923
1061
|
}
|
|
924
1062
|
/**
|
|
925
1063
|
* Remove the integration metadata cache for this session.
|
|
@@ -1256,12 +1394,16 @@ export class AiService extends TracedEventEmitter {
|
|
|
1256
1394
|
* per ai-service lifetime. The disk checklist is the recovery source of
|
|
1257
1395
|
* truth across process restarts.
|
|
1258
1396
|
*
|
|
1259
|
-
*
|
|
1260
|
-
*
|
|
1261
|
-
*
|
|
1262
|
-
*
|
|
1397
|
+
* Primary auto-trigger: readiness gate (`notifyMigrationAppArtifactsReady`,
|
|
1398
|
+
* `handleUserConnected`, `updateClarkJwt`) →
|
|
1399
|
+
* `tryAutoDispatchMigrationTurnIfReady` → `maybeAutoDispatchMigrationTurn`.
|
|
1400
|
+
* Backup caller: the UI RPC (see v1.ai.triggerMigrationTurn) once it
|
|
1401
|
+
* observes the post-flip state via /sb-migration-status.
|
|
1402
|
+
* User retry after unresolved failures: UI RPC with
|
|
1403
|
+
* `retryMode: "focused-debug"` after /sb-migration-retry-unresolved.
|
|
1263
1404
|
*/
|
|
1264
1405
|
async handleAiTriggerMigrationTurn(request) {
|
|
1406
|
+
this.storeMigrationTurnCredentials(request.jwt, request.llmConfig);
|
|
1265
1407
|
// User-initiated "Fix with Clark" retries bypass the one-shot
|
|
1266
1408
|
// guard. The HTTP route that flips the items has already landed,
|
|
1267
1409
|
// so if we refused here the user would be stuck.
|
|
@@ -1287,8 +1429,10 @@ export class AiService extends TracedEventEmitter {
|
|
|
1287
1429
|
return { dispatched: false, reason: "awaiting-interactive-response" };
|
|
1288
1430
|
}
|
|
1289
1431
|
}
|
|
1432
|
+
this.migrationTurnTriggered = true;
|
|
1290
1433
|
const checklist = await readPersistedChecklist(this.appRootDirPath);
|
|
1291
1434
|
if (!checklist) {
|
|
1435
|
+
this.migrationTurnTriggered = false;
|
|
1292
1436
|
this.getLogger().warn("[ai-service] Migration checklist not found or unreadable; skipping translation turn");
|
|
1293
1437
|
return { dispatched: false, reason: "checklist-unavailable" };
|
|
1294
1438
|
}
|
|
@@ -1296,6 +1440,7 @@ export class AiService extends TracedEventEmitter {
|
|
|
1296
1440
|
(item.status === "pending" || item.status === "in_progress"));
|
|
1297
1441
|
const pendingSeedApiCount = pendingSeedApiItems.length;
|
|
1298
1442
|
if (pendingSeedApiCount === 0) {
|
|
1443
|
+
this.migrationTurnTriggered = false;
|
|
1299
1444
|
return { dispatched: false, reason: "no-pending-items" };
|
|
1300
1445
|
}
|
|
1301
1446
|
// Pre-flight quota gate. The migration turn drives LLM inference (which
|
|
@@ -1307,10 +1452,10 @@ export class AiService extends TracedEventEmitter {
|
|
|
1307
1452
|
// same pre-flight check handleAiGenerate already runs.
|
|
1308
1453
|
const quota = await this.checkAiQuota(request.jwt);
|
|
1309
1454
|
if (!quota.allowed) {
|
|
1455
|
+
this.migrationTurnTriggered = false;
|
|
1310
1456
|
this.getLogger().warn("[ai-service] Skipping v2→v3 migration turn — AI quota exceeded", { reason: quota.reason });
|
|
1311
1457
|
return { dispatched: false, reason: "quota-exceeded" };
|
|
1312
1458
|
}
|
|
1313
|
-
this.migrationTurnTriggered = true;
|
|
1314
1459
|
this.appShell.setApiHandlerEnabled(false);
|
|
1315
1460
|
this.getLogger().info(`[ai-service] Dispatching internal v2→v3 migration turn for ${pendingSeedApiCount} API(s) (API VFS projection disabled, retryMode=${request.retryMode ?? "none"})`);
|
|
1316
1461
|
const prompt = buildTranslationPrompt({
|
|
@@ -1332,6 +1477,8 @@ export class AiService extends TracedEventEmitter {
|
|
|
1332
1477
|
origin: "app_migration",
|
|
1333
1478
|
pendingSeedApiCount,
|
|
1334
1479
|
retryMode: request.retryMode ?? "none",
|
|
1480
|
+
triggeredBy: request.triggeredBy ??
|
|
1481
|
+
(request.retryMode === "focused-debug" ? "focused-debug" : "ui-rpc"),
|
|
1335
1482
|
};
|
|
1336
1483
|
this.clark.updateContext((context) => ({
|
|
1337
1484
|
...context,
|
|
@@ -1676,6 +1823,7 @@ export class AiService extends TracedEventEmitter {
|
|
|
1676
1823
|
}
|
|
1677
1824
|
async handleAiGenerate(request) {
|
|
1678
1825
|
this.getLogger().info(`[ai-service] handleAiGenerate: peerId=${this.stablePeer.peerId ?? "unknown"}`);
|
|
1826
|
+
this.storeMigrationTurnCredentials(request.jwt, request.llmConfig);
|
|
1679
1827
|
if (this.clark.state === ClarkStateNames.Dead) {
|
|
1680
1828
|
throw new Error("Service is unavailable");
|
|
1681
1829
|
}
|
|
@@ -2886,6 +3034,12 @@ export class AiService extends TracedEventEmitter {
|
|
|
2886
3034
|
}
|
|
2887
3035
|
return `Continue with the task using alternative approaches. The tool ${toolName} was denied permission.`;
|
|
2888
3036
|
}
|
|
3037
|
+
resolveGenerationStateForUi() {
|
|
3038
|
+
return resolveGenerationStateForUi({
|
|
3039
|
+
clarkState: this.clark.state,
|
|
3040
|
+
lastGenerationState: this.clark.context.lastGenerationState,
|
|
3041
|
+
});
|
|
3042
|
+
}
|
|
2889
3043
|
handleUserConnected(peer, peerId) {
|
|
2890
3044
|
const existingPeerId = this.stablePeer.peerId;
|
|
2891
3045
|
this.getLogger().info(`[ai-service] handleUserConnected: peerId=${peerId}`);
|
|
@@ -2917,9 +3071,10 @@ export class AiService extends TracedEventEmitter {
|
|
|
2917
3071
|
this.authenticatedPeerUserId = undefined;
|
|
2918
3072
|
}
|
|
2919
3073
|
// 1. Sync generation state if generation is in progress
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
3074
|
+
const generationState = this.resolveGenerationStateForUi();
|
|
3075
|
+
if (generationState) {
|
|
3076
|
+
this.getLogger().info(`[ai-service] Syncing generation state on reconnect: ${generationState.state}`);
|
|
3077
|
+
catchBackgroundPeerDisconnect(peer.call.aiSetGenerationState(generationState), "generation state reconnect push");
|
|
2923
3078
|
}
|
|
2924
3079
|
// 2. Sync tool permission state with the UI
|
|
2925
3080
|
if (this.clark.context.pendingToolPermissionRequest) {
|
|
@@ -2970,6 +3125,7 @@ export class AiService extends TracedEventEmitter {
|
|
|
2970
3125
|
if (this.taskStore) {
|
|
2971
3126
|
this.pendingTaskResyncPeerIds.add(peerId);
|
|
2972
3127
|
}
|
|
3128
|
+
this.tryAutoDispatchMigrationTurnIfReady();
|
|
2973
3129
|
}
|
|
2974
3130
|
/**
|
|
2975
3131
|
* Per-session set of peer IDs that connected since their last task
|