@makerbi/remodex 3.1.0 → 3.3.0
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/package.json +1 -1
- package/src/bridge.js +160 -30
- package/src/codex-desktop-refresher.js +8 -8
- package/src/codex-runtime-settings.js +113 -0
- package/src/desktop-ipc-action-follower.js +295 -104
- package/src/desktop-ipc-conversation-adapter.js +250 -45
- package/src/desktop-ipc-conversation-projector.js +1 -0
- package/src/desktop-ipc-live-owner.js +269 -178
- package/src/desktop-ipc-shared.js +37 -3
- package/src/git-handler.js +20 -17
- package/src/rollout-live-mirror.js +3 -4
- package/src/runtime-provider-router.js +10 -2
- package/src/thread-activity-projector.js +694 -0
- package/src/thread-activity-store.js +325 -0
- package/src/thread-runtime-settings-store.js +60 -74
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// Depends on: crypto, ./desktop-ipc-shared
|
|
6
6
|
|
|
7
7
|
const { randomUUID } = require("crypto");
|
|
8
|
+
const { applyRuntimeSettingsToConversation } = require("./codex-runtime-settings");
|
|
8
9
|
|
|
9
10
|
const {
|
|
10
11
|
cloneJSON,
|
|
@@ -190,11 +191,15 @@ function applyAppServerMessageToConversationState({
|
|
|
190
191
|
return null;
|
|
191
192
|
}
|
|
192
193
|
const conversation = ensureConversationInMap(conversations, threadId, { hostId, now });
|
|
193
|
-
|
|
194
|
+
const title = readString(message.params?.threadName)
|
|
194
195
|
|| readString(message.params?.thread_name)
|
|
195
196
|
|| readString(message.params?.name)
|
|
196
197
|
|| readString(message.params?.title)
|
|
197
198
|
|| conversation.title;
|
|
199
|
+
if (title === conversation.title) {
|
|
200
|
+
return { threadId, changed: false };
|
|
201
|
+
}
|
|
202
|
+
conversation.title = title;
|
|
198
203
|
conversation.updatedAt = now();
|
|
199
204
|
return { threadId, changed: true };
|
|
200
205
|
}
|
|
@@ -446,7 +451,8 @@ function buildConversationStateFromThread(thread, {
|
|
|
446
451
|
const createdAtMs = timestampSecondsToMs(thread?.createdAt) || previous?.createdAt || now();
|
|
447
452
|
const updatedAtMs = timestampSecondsToMs(thread?.updatedAt) || now();
|
|
448
453
|
const cwd = readString(thread?.cwd) || previous?.cwd || "";
|
|
449
|
-
const latestModel = readString(
|
|
454
|
+
const latestModel = readString(previous?.latestThreadSettings?.model)
|
|
455
|
+
|| readString(thread?.model) || previous?.latestModel || "";
|
|
450
456
|
const turns = mergeConversationTurnsFromThread(thread?.turns, {
|
|
451
457
|
previousTurns: previous?.turns,
|
|
452
458
|
threadId,
|
|
@@ -454,17 +460,28 @@ function buildConversationStateFromThread(thread, {
|
|
|
454
460
|
now,
|
|
455
461
|
});
|
|
456
462
|
|
|
457
|
-
|
|
463
|
+
const state = {
|
|
458
464
|
id: threadId,
|
|
465
|
+
forkedFromId: previous?.forkedFromId || null,
|
|
459
466
|
hostId,
|
|
460
467
|
turns,
|
|
461
468
|
requests: cloneJSON(previous?.requests || []),
|
|
462
469
|
createdAt: createdAtMs,
|
|
463
470
|
updatedAt: updatedAtMs,
|
|
471
|
+
recencyAt: updatedAtMs,
|
|
464
472
|
title: readString(thread?.name) || previous?.title || null,
|
|
473
|
+
source: readString(thread?.source) || previous?.source || "vscode",
|
|
474
|
+
agentNickname: previous?.agentNickname || null,
|
|
475
|
+
threadSource: readString(thread?.threadSource) || previous?.threadSource || "user",
|
|
476
|
+
historyMode: previous?.historyMode || "legacy",
|
|
477
|
+
parentThreadId: previous?.parentThreadId || null,
|
|
478
|
+
mode: previous?.mode || "default",
|
|
479
|
+
threadStartKind: previous?.threadStartKind || "default",
|
|
480
|
+
modelProvider: readString(thread?.modelProvider) || previous?.modelProvider || "openai",
|
|
465
481
|
latestModel,
|
|
466
|
-
latestReasoningEffort: previous?.latestReasoningEffort
|
|
467
|
-
latestServiceTier: previous?.latestServiceTier
|
|
482
|
+
latestReasoningEffort: previous?.latestReasoningEffort ?? null,
|
|
483
|
+
latestServiceTier: previous?.latestServiceTier ?? null,
|
|
484
|
+
latestThreadSettings: cloneJSON(previous?.latestThreadSettings || null),
|
|
468
485
|
previousTurnModel: previous?.previousTurnModel || null,
|
|
469
486
|
latestCollaborationMode: previous?.latestCollaborationMode || {
|
|
470
487
|
mode: "default",
|
|
@@ -488,7 +505,10 @@ function buildConversationStateFromThread(thread, {
|
|
|
488
505
|
workspaceBrowserRoot: previous?.workspaceBrowserRoot || null,
|
|
489
506
|
projectlessOutputDirectory: previous?.projectlessOutputDirectory || null,
|
|
490
507
|
currentPermissions: cloneJSON(previous?.currentPermissions || null),
|
|
508
|
+
sessionId: readString(thread?.sessionId) || previous?.sessionId || null,
|
|
491
509
|
};
|
|
510
|
+
synchronizeDesktopConversationCompatibility(state);
|
|
511
|
+
return state;
|
|
492
512
|
}
|
|
493
513
|
|
|
494
514
|
function mergeConversationTurnsFromThread(threadTurns, {
|
|
@@ -552,7 +572,7 @@ function createEmptyConversationState(threadId, {
|
|
|
552
572
|
cwd = "",
|
|
553
573
|
} = {}) {
|
|
554
574
|
const timestamp = now();
|
|
555
|
-
|
|
575
|
+
const state = {
|
|
556
576
|
id: threadId,
|
|
557
577
|
hostId,
|
|
558
578
|
turns: [],
|
|
@@ -587,6 +607,187 @@ function createEmptyConversationState(threadId, {
|
|
|
587
607
|
projectlessOutputDirectory: null,
|
|
588
608
|
currentPermissions: null,
|
|
589
609
|
};
|
|
610
|
+
synchronizeDesktopConversationCompatibility(state);
|
|
611
|
+
return state;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// Desktop 26.825 moved rendered history to a canonical entity graph. It still
|
|
615
|
+
// accepts legacy turns during normalization, but unified-timeline selectors now
|
|
616
|
+
// assume the graph and several nested collections exist. Keep the bridge's
|
|
617
|
+
// mutable legacy turns for app-server event handling, and mirror them into the
|
|
618
|
+
// current Desktop shape before every stream broadcast.
|
|
619
|
+
function synchronizeDesktopConversationCompatibility(state) {
|
|
620
|
+
if (!state || typeof state !== "object" || Array.isArray(state)) {
|
|
621
|
+
return state;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
const turns = Array.isArray(state.turns) ? state.turns : [];
|
|
625
|
+
const entries = [];
|
|
626
|
+
const entitiesByKey = {};
|
|
627
|
+
for (const turn of turns) {
|
|
628
|
+
const turnId = readString(turn?.turnId) || readString(turn?.id);
|
|
629
|
+
if (!turnId) {
|
|
630
|
+
continue;
|
|
631
|
+
}
|
|
632
|
+
turn.params = normalizeTurnParamsCompatibility(turn.params, {
|
|
633
|
+
cwd: readString(turn.params?.cwd) || readString(state.cwd),
|
|
634
|
+
});
|
|
635
|
+
turn.items = Array.isArray(turn.items) ? turn.items.map(normalizeDesktopItemCompatibility) : [];
|
|
636
|
+
turn.hookRuns = Array.isArray(turn.hookRuns) ? turn.hookRuns : [];
|
|
637
|
+
const key = `turn:${turnId}`;
|
|
638
|
+
entries.push({ key, value: key });
|
|
639
|
+
const { id: _legacyId, ...canonicalTurn } = turn;
|
|
640
|
+
entitiesByKey[key] = {
|
|
641
|
+
...canonicalTurn,
|
|
642
|
+
turnId,
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
const islandId = "tail:0";
|
|
647
|
+
state.turnHistory = {
|
|
648
|
+
kind: "canonical",
|
|
649
|
+
history: {
|
|
650
|
+
entitiesByKey,
|
|
651
|
+
generation: 0,
|
|
652
|
+
isComplete: true,
|
|
653
|
+
islands: [{
|
|
654
|
+
id: islandId,
|
|
655
|
+
entries,
|
|
656
|
+
olderBoundary: {
|
|
657
|
+
status: "exhausted",
|
|
658
|
+
boundaryId: `${islandId}:older`,
|
|
659
|
+
},
|
|
660
|
+
newerBoundary: {
|
|
661
|
+
status: "exhausted",
|
|
662
|
+
boundaryId: `${islandId}:newer`,
|
|
663
|
+
},
|
|
664
|
+
}],
|
|
665
|
+
},
|
|
666
|
+
};
|
|
667
|
+
state.turnsPagination = {
|
|
668
|
+
olderCursor: null,
|
|
669
|
+
oldestLoadedTurnId: readString(turns[0]?.turnId) || readString(turns[0]?.id) || null,
|
|
670
|
+
isLoadingOlder: false,
|
|
671
|
+
hasLoadedOldest: true,
|
|
672
|
+
};
|
|
673
|
+
|
|
674
|
+
const latestParams = [...turns]
|
|
675
|
+
.reverse()
|
|
676
|
+
.map((turn) => turn?.params)
|
|
677
|
+
.find((params) => params && typeof params === "object") || null;
|
|
678
|
+
const sandboxPolicy = normalizeSandboxPolicyCompatibility(
|
|
679
|
+
latestParams?.sandboxPolicy || state.currentPermissions?.sandboxPolicy
|
|
680
|
+
);
|
|
681
|
+
if (sandboxPolicy) {
|
|
682
|
+
const runtimeWorkspaceRoots = Array.isArray(latestParams?.runtimeWorkspaceRoots)
|
|
683
|
+
? cloneJSON(latestParams.runtimeWorkspaceRoots)
|
|
684
|
+
: Array.isArray(state.currentPermissions?.runtimeWorkspaceRoots)
|
|
685
|
+
? cloneJSON(state.currentPermissions.runtimeWorkspaceRoots)
|
|
686
|
+
: [];
|
|
687
|
+
state.currentPermissions = {
|
|
688
|
+
activePermissionProfile: cloneJSON(
|
|
689
|
+
latestParams?.activePermissionProfile
|
|
690
|
+
?? state.currentPermissions?.activePermissionProfile
|
|
691
|
+
?? permissionProfileFromId(latestParams?.permissions)
|
|
692
|
+
),
|
|
693
|
+
approvalPolicy: latestParams?.approvalPolicy
|
|
694
|
+
?? state.currentPermissions?.approvalPolicy
|
|
695
|
+
?? "on-request",
|
|
696
|
+
approvalsReviewer: latestParams?.approvalsReviewer
|
|
697
|
+
?? state.currentPermissions?.approvalsReviewer
|
|
698
|
+
?? "user",
|
|
699
|
+
runtimeWorkspaceRoots,
|
|
700
|
+
sandboxPolicy,
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
state.recencyAt = Number.isFinite(state.recencyAt) ? state.recencyAt : state.updatedAt;
|
|
705
|
+
state.source ||= "vscode";
|
|
706
|
+
state.threadSource ||= "user";
|
|
707
|
+
state.historyMode ||= "legacy";
|
|
708
|
+
state.mode ||= "default";
|
|
709
|
+
state.threadStartKind ||= "default";
|
|
710
|
+
state.modelProvider ||= "openai";
|
|
711
|
+
state.latestThreadSettings = {
|
|
712
|
+
cwd: readString(latestParams?.cwd) || readString(state.cwd) || null,
|
|
713
|
+
approvalPolicy: latestParams?.approvalPolicy ?? state.currentPermissions?.approvalPolicy ?? null,
|
|
714
|
+
approvalsReviewer: latestParams?.approvalsReviewer
|
|
715
|
+
?? state.currentPermissions?.approvalsReviewer
|
|
716
|
+
?? null,
|
|
717
|
+
...(sandboxPolicy ? { sandboxPolicy } : {}),
|
|
718
|
+
activePermissionProfile: cloneJSON(state.currentPermissions?.activePermissionProfile ?? null),
|
|
719
|
+
model: readString(state.latestThreadSettings?.model)
|
|
720
|
+
|| readString(latestParams?.model)
|
|
721
|
+
|| readString(state.latestModel)
|
|
722
|
+
|| null,
|
|
723
|
+
modelProvider: readString(state.latestThreadSettings?.modelProvider)
|
|
724
|
+
|| readString(state.modelProvider)
|
|
725
|
+
|| "openai",
|
|
726
|
+
serviceTier: Object.prototype.hasOwnProperty.call(state.latestThreadSettings || {}, "serviceTier")
|
|
727
|
+
? state.latestThreadSettings.serviceTier
|
|
728
|
+
: latestParams?.serviceTier ?? state.latestServiceTier ?? null,
|
|
729
|
+
effort: Object.prototype.hasOwnProperty.call(state.latestThreadSettings || {}, "effort")
|
|
730
|
+
? state.latestThreadSettings.effort
|
|
731
|
+
: latestParams?.effort ?? state.latestReasoningEffort ?? null,
|
|
732
|
+
summary: latestParams?.summary ?? state.latestThreadSettings?.summary ?? "none",
|
|
733
|
+
collaborationMode: cloneJSON(
|
|
734
|
+
state.latestThreadSettings?.collaborationMode
|
|
735
|
+
|| latestParams?.collaborationMode
|
|
736
|
+
|| state.latestCollaborationMode
|
|
737
|
+
|| null
|
|
738
|
+
),
|
|
739
|
+
multiAgentMode: latestParams?.multiAgentMode
|
|
740
|
+
?? state.latestThreadSettings?.multiAgentMode
|
|
741
|
+
?? null,
|
|
742
|
+
personality: latestParams?.personality
|
|
743
|
+
?? state.latestThreadSettings?.personality
|
|
744
|
+
?? null,
|
|
745
|
+
};
|
|
746
|
+
return state;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
function normalizeTurnParamsCompatibility(params, { cwd = "" } = {}) {
|
|
750
|
+
const normalized = params && typeof params === "object" && !Array.isArray(params)
|
|
751
|
+
? params
|
|
752
|
+
: {};
|
|
753
|
+
normalized.input = normalizeDesktopInputEntries(normalized.input);
|
|
754
|
+
normalized.attachments = Array.isArray(normalized.attachments) ? normalized.attachments : [];
|
|
755
|
+
normalized.cwd = readString(normalized.cwd) || readString(cwd) || null;
|
|
756
|
+
normalized.summary ??= "none";
|
|
757
|
+
normalized.personality ??= null;
|
|
758
|
+
normalized.outputSchema ??= null;
|
|
759
|
+
normalized.collaborationMode ??= null;
|
|
760
|
+
const sandboxPolicy = normalizeSandboxPolicyCompatibility(normalized.sandboxPolicy);
|
|
761
|
+
if (sandboxPolicy) {
|
|
762
|
+
normalized.sandboxPolicy = sandboxPolicy;
|
|
763
|
+
}
|
|
764
|
+
return normalized;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
function normalizeSandboxPolicyCompatibility(policy) {
|
|
768
|
+
if (!policy || typeof policy !== "object" || Array.isArray(policy)) {
|
|
769
|
+
return null;
|
|
770
|
+
}
|
|
771
|
+
const normalized = cloneJSON(policy);
|
|
772
|
+
if (normalizeToken(normalized.type) === "workspacewrite") {
|
|
773
|
+
normalized.type = "workspaceWrite";
|
|
774
|
+
normalized.writableRoots = Array.isArray(normalized.writableRoots)
|
|
775
|
+
? normalized.writableRoots
|
|
776
|
+
: [];
|
|
777
|
+
normalized.excludeSlashTmp = Boolean(normalized.excludeSlashTmp);
|
|
778
|
+
normalized.excludeTmpdirEnvVar = Boolean(normalized.excludeTmpdirEnvVar);
|
|
779
|
+
normalized.networkAccess = Boolean(normalized.networkAccess);
|
|
780
|
+
}
|
|
781
|
+
if (normalizeToken(normalized.type) === "readonly") {
|
|
782
|
+
normalized.type = "readOnly";
|
|
783
|
+
normalized.networkAccess = Boolean(normalized.networkAccess);
|
|
784
|
+
}
|
|
785
|
+
return normalized;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
function permissionProfileFromId(value) {
|
|
789
|
+
const id = readString(value);
|
|
790
|
+
return id ? { id, extends: null } : null;
|
|
590
791
|
}
|
|
591
792
|
|
|
592
793
|
function buildConversationTurn(turn, {
|
|
@@ -596,7 +797,7 @@ function buildConversationTurn(turn, {
|
|
|
596
797
|
now = () => Date.now(),
|
|
597
798
|
} = {}) {
|
|
598
799
|
const turnId = readString(turn?.id) || readString(turn?.turnId) || readString(turn?.turn_id);
|
|
599
|
-
const params = cloneJSON(previousTurn?.params || {
|
|
800
|
+
const params = normalizeTurnParamsCompatibility(cloneJSON(previousTurn?.params || {
|
|
600
801
|
threadId,
|
|
601
802
|
input: [],
|
|
602
803
|
cwd: cwd || null,
|
|
@@ -611,7 +812,7 @@ function buildConversationTurn(turn, {
|
|
|
611
812
|
outputSchema: null,
|
|
612
813
|
collaborationMode: null,
|
|
613
814
|
attachments: [],
|
|
614
|
-
});
|
|
815
|
+
}), { cwd });
|
|
615
816
|
const builtTurn = {
|
|
616
817
|
id: turnId,
|
|
617
818
|
turnId,
|
|
@@ -678,6 +879,9 @@ function applyPendingTurnStartParams(
|
|
|
678
879
|
...turn.params,
|
|
679
880
|
...cloneJSON(pendingParams),
|
|
680
881
|
};
|
|
882
|
+
turn.params = normalizeTurnParamsCompatibility(turn.params, {
|
|
883
|
+
cwd: readString(turn.params?.cwd) || readString(conversation?.cwd),
|
|
884
|
+
});
|
|
681
885
|
normalizeTurnInitialPrompt(turn);
|
|
682
886
|
}
|
|
683
887
|
|
|
@@ -695,35 +899,8 @@ function applyTurnRuntimeMetadata(conversation, turnParams) {
|
|
|
695
899
|
if (!conversation || !turnParams) {
|
|
696
900
|
return;
|
|
697
901
|
}
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
const serviceTier = readString(turnParams.serviceTier) || null;
|
|
701
|
-
if (model) {
|
|
702
|
-
conversation.previousTurnModel = conversation.latestModel || null;
|
|
703
|
-
conversation.latestModel = model;
|
|
704
|
-
}
|
|
705
|
-
if (effort) {
|
|
706
|
-
conversation.latestReasoningEffort = effort;
|
|
707
|
-
}
|
|
708
|
-
conversation.latestServiceTier = serviceTier;
|
|
709
|
-
if (turnParams.collaborationMode && typeof turnParams.collaborationMode === "object") {
|
|
710
|
-
conversation.latestCollaborationMode = cloneJSON(turnParams.collaborationMode);
|
|
711
|
-
return;
|
|
712
|
-
}
|
|
713
|
-
if (!model && !effort) {
|
|
714
|
-
return;
|
|
715
|
-
}
|
|
716
|
-
const settings = conversation.latestCollaborationMode?.settings;
|
|
717
|
-
conversation.latestCollaborationMode = {
|
|
718
|
-
mode: conversation.latestCollaborationMode?.mode || "default",
|
|
719
|
-
settings: {
|
|
720
|
-
...(settings && typeof settings === "object" ? settings : {
|
|
721
|
-
developer_instructions: null,
|
|
722
|
-
}),
|
|
723
|
-
model: model || settings?.model || "",
|
|
724
|
-
reasoning_effort: effort || settings?.reasoning_effort || null,
|
|
725
|
-
},
|
|
726
|
-
};
|
|
902
|
+
if (readString(turnParams.model)) conversation.previousTurnModel = conversation.latestModel || null;
|
|
903
|
+
applyRuntimeSettingsToConversation(conversation, turnParams);
|
|
727
904
|
}
|
|
728
905
|
|
|
729
906
|
function turnHasUserMessageItem(turn) {
|
|
@@ -763,7 +940,22 @@ function extractUserText(entries) {
|
|
|
763
940
|
}
|
|
764
941
|
|
|
765
942
|
function sanitizeUserInputEntries(entries) {
|
|
766
|
-
return sanitizeSharedUserInputEntries(entries).map(cloneJSON);
|
|
943
|
+
return normalizeDesktopInputEntries(sanitizeSharedUserInputEntries(entries)).map(cloneJSON);
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
// App-server defaults text_elements, but Desktop 26.903 reads its length
|
|
947
|
+
// directly in IPC snapshots. Preserve existing spans and their byte offsets.
|
|
948
|
+
function normalizeDesktopInputEntries(entries) {
|
|
949
|
+
if (!Array.isArray(entries)) {
|
|
950
|
+
return [];
|
|
951
|
+
}
|
|
952
|
+
return entries.map((entry) => {
|
|
953
|
+
if (!entry || typeof entry !== "object" || entry.type !== "text"
|
|
954
|
+
|| Array.isArray(entry.text_elements)) {
|
|
955
|
+
return entry;
|
|
956
|
+
}
|
|
957
|
+
return { ...entry, text_elements: [] };
|
|
958
|
+
});
|
|
767
959
|
}
|
|
768
960
|
|
|
769
961
|
function sanitizeUserMessageItem(item) {
|
|
@@ -784,15 +976,22 @@ function sanitizeUserMessageItem(item) {
|
|
|
784
976
|
};
|
|
785
977
|
}
|
|
786
978
|
|
|
787
|
-
//
|
|
788
|
-
// while the matching Desktop renderer reads that collection without a fallback.
|
|
789
|
-
// Keep the richer snapshots unchanged and synthesize lightweight references from
|
|
790
|
-
// receiverThreadIds for older/CLI-owned rollouts so opening them cannot crash.
|
|
979
|
+
// Normalize optional app-server fields required by Desktop's snapshot renderer.
|
|
791
980
|
function normalizeDesktopItemCompatibility(item) {
|
|
792
|
-
if (!item || typeof item !== "object"
|
|
981
|
+
if (!item || typeof item !== "object") {
|
|
982
|
+
return item;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
if (item.type === "userMessage" || item.type === "steeringUserMessage") {
|
|
986
|
+
const inputKey = item.type === "userMessage" ? "content" : "input";
|
|
987
|
+
return { ...item, [inputKey]: normalizeDesktopInputEntries(item[inputKey]) };
|
|
988
|
+
}
|
|
989
|
+
if (normalizeToken(item.type) !== "collabagenttoolcall") {
|
|
793
990
|
return item;
|
|
794
991
|
}
|
|
795
992
|
|
|
993
|
+
// Codex CLI 0.144.1 can omit receiverThreads from persisted collab tool calls.
|
|
994
|
+
// Keep richer snapshots and synthesize references for older/CLI-owned rollouts.
|
|
796
995
|
const receiverThreads = Array.isArray(item.receiverThreads)
|
|
797
996
|
? item.receiverThreads
|
|
798
997
|
: [];
|
|
@@ -886,14 +1085,19 @@ function normalizeTurnInitialPrompt(turn) {
|
|
|
886
1085
|
function userMessageContentFromTurnInput(entry) {
|
|
887
1086
|
if (typeof entry === "string") {
|
|
888
1087
|
const text = readString(entry);
|
|
889
|
-
return text ? { type: "text", text } : null;
|
|
1088
|
+
return text ? { type: "text", text, text_elements: [] } : null;
|
|
890
1089
|
}
|
|
891
1090
|
if (!entry || typeof entry !== "object") {
|
|
892
1091
|
return null;
|
|
893
1092
|
}
|
|
894
1093
|
const type = normalizeToken(entry.type);
|
|
895
1094
|
if (type === "inputtext" || type === "text") {
|
|
896
|
-
return {
|
|
1095
|
+
return {
|
|
1096
|
+
...cloneJSON(entry),
|
|
1097
|
+
type: "text",
|
|
1098
|
+
text: typeof entry.text === "string" ? entry.text : "",
|
|
1099
|
+
text_elements: Array.isArray(entry.text_elements) ? cloneJSON(entry.text_elements) : [],
|
|
1100
|
+
};
|
|
897
1101
|
}
|
|
898
1102
|
return cloneJSON(entry);
|
|
899
1103
|
}
|
|
@@ -1262,6 +1466,7 @@ module.exports = {
|
|
|
1262
1466
|
readThreadIdFromParams,
|
|
1263
1467
|
readTurnIdFromParams,
|
|
1264
1468
|
readTurnIdFromTurn,
|
|
1469
|
+
synchronizeDesktopConversationCompatibility,
|
|
1265
1470
|
timestampSecondsToMs,
|
|
1266
1471
|
upsertItem,
|
|
1267
1472
|
upsertTurn,
|
|
@@ -203,6 +203,7 @@ function projectConversationState(threadId, rawState, {
|
|
|
203
203
|
|| readString(rawState?.latest_model)
|
|
204
204
|
|| "",
|
|
205
205
|
...(runtimeSettings ? {
|
|
206
|
+
runtimeSettings: cloneJSON(runtimeSettings),
|
|
206
207
|
reasoningEffort: readString(runtimeSettings.reasoningEffort) || null,
|
|
207
208
|
serviceTier: readString(runtimeSettings.serviceTier) || null,
|
|
208
209
|
runtimeSettingsRevision: Number(runtimeSettings.revision) || 0,
|