nolo-cli 0.157.0-alpha.1 → 0.158.0-alpha.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/{_executeModel-5WS2PA62.js → _executeModel-6BMU3URY.js} +35 -35
- package/{accountResolver-7RYB4D2P.js → accountResolver-55EDKEIK.js} +1 -1
- package/{action-ZJYUBXFC.js → action-GPPJC5TI.js} +4 -4
- package/{addContentAction-TVHB4526.js → addContentAction-BI6RDRTQ.js} +7 -7
- package/{addDialogAgentAction-FDPBU6K6.js → addDialogAgentAction-4RJYUSIK.js} +6 -6
- package/{agentDeleteCommand-Q6M4F3U6.js → agentDeleteCommand-Q2XWGBC2.js} +42 -42
- package/{agentEmailCommands-FNH6FEHS.js → agentEmailCommands-XFBE2A3F.js} +44 -44
- package/{agentListCommands-JUNMFS6E.js → agentListCommands-OROMT4P3.js} +12 -12
- package/{agentMachineCommands-VNLDEKNT.js → agentMachineCommands-ULK5YKKJ.js} +11 -10
- package/{agentProviderCommands-X2HQE6HY.js → agentProviderCommands-MKG2OOEY.js} +2 -2
- package/{agentRecordCommands-47XXRVPI.js → agentRecordCommands-3VHBLS6P.js} +42 -42
- package/{agentRunCommand-QEXFJUXQ.js → agentRunCommand-LCIMEAQY.js} +44 -43
- package/{agentRuntimeLocal-O5GDAFTN.js → agentRuntimeLocal-NPJS2QDP.js} +5 -5
- package/{agentSlice-E3XS5FTQ.js → agentSlice-VRAPG6CH.js} +7 -7
- package/{appDeleteCommands-C2J5RQ3I.js → appDeleteCommands-AZ3KS4HK.js} +10 -10
- package/{appDeployCommands-3YRK7PSU.js → appDeployCommands-BTV22ICJ.js} +10 -10
- package/{appDeployStatusCommands-FPAX7MOK.js → appDeployStatusCommands-JSW3HPIW.js} +10 -10
- package/{appGetCommands-XAC2V766.js → appGetCommands-5KTTFIMV.js} +10 -10
- package/{appListCommands-ZJL2W5O7.js → appListCommands-3BJPAE2U.js} +10 -10
- package/{authCommand-J3XILHWW.js → authCommand-NIV3DKPF.js} +7 -287
- package/{authCommands-77CHYBGF.js → authCommands-AMNIAKEG.js} +2 -2
- package/{builtinSkillRegistry-A6VSPJEJ.js → builtinSkillRegistry-H3AY27TR.js} +1 -1
- package/{chromeCommands-OBBNJCLS.js → chromeCommands-IY4NVSXZ.js} +17 -10
- package/{chunk-SW4S4XYB.js → chunk-2AB2HA4M.js} +84 -34
- package/{chunk-VSOWPETY.js → chunk-2BKUVRC5.js} +7 -7
- package/{chunk-Z6KQDSZW.js → chunk-2SGAI64X.js} +2 -2
- package/{chunk-KOB75UNU.js → chunk-2SOS7OSQ.js} +18 -2
- package/{chunk-C5VPAHIU.js → chunk-32ZKZET7.js} +1 -1
- package/{chunk-XPWGOTBQ.js → chunk-3L2WKC3W.js} +1 -8
- package/{chunk-PEO24UB5.js → chunk-3TBHZPNG.js} +33 -6
- package/{chunk-YBNHPX4S.js → chunk-4RJJDA57.js} +1 -1
- package/{chunk-X5SUT4CN.js → chunk-4UOEOHY3.js} +6 -6
- package/{chunk-UUPR3TD7.js → chunk-7RF4O6AT.js} +1 -3
- package/{chunk-FPWT3RH2.js → chunk-AJ4V34SG.js} +10 -10
- package/{chunk-2GGXHQIW.js → chunk-BLVSFYQ3.js} +4 -2
- package/{chunk-SKPPKHD3.js → chunk-BYQOCH75.js} +2 -2
- package/{chunk-UTIMX333.js → chunk-C3OK72G3.js} +1 -1
- package/{chunk-ZWG3C7VI.js → chunk-C6FY7HWI.js} +35 -0
- package/{chunk-RUNKPFM5.js → chunk-CDWHHLK5.js} +12 -8
- package/{chunk-ROPSATAB.js → chunk-CON6SI7N.js} +1 -1
- package/{chunk-4Z245KOA.js → chunk-DC3SZCRR.js} +6 -2
- package/{chunk-OH2M7WEU.js → chunk-EQGFFDNA.js} +3 -3
- package/{chunk-ANJTRG52.js → chunk-G2WP7VPD.js} +0 -37
- package/{chunk-7A4LJCDR.js → chunk-G476FQ7Q.js} +4 -4
- package/{chunk-DW7MGLMG.js → chunk-GAVUTXM5.js} +21 -17
- package/{chunk-PSJWPSKS.js → chunk-HB4XPBC7.js} +0 -32
- package/{chunk-6MJNEXUU.js → chunk-HGDKT2D6.js} +4 -0
- package/{chunk-EM3YOZJ4.js → chunk-ICRRXBRN.js} +3 -3
- package/{chunk-7KYVUFDG.js → chunk-IE5PXKVU.js} +1 -263
- package/{chunk-T6CBQ6BN.js → chunk-INFHX73M.js} +1 -1
- package/{chunk-CE7PIHQD.js → chunk-IRTOYSA2.js} +3 -3
- package/{chunk-WZ6OU4NX.js → chunk-J2ATF74A.js} +2 -2
- package/{chunk-TJ2VPCBE.js → chunk-JPJGMOIM.js} +2 -2
- package/{chunk-I2ZMGXXF.js → chunk-KFHREHUQ.js} +1 -1
- package/{chunk-7GC3EKUG.js → chunk-KKKHAF3P.js} +2 -2
- package/{chunk-KX6LPG7W.js → chunk-KLA62VVE.js} +1 -1
- package/{chunk-TYND6RDQ.js → chunk-LV4LV2B4.js} +72 -1
- package/{chunk-TZTWMGE3.js → chunk-M2P3OGXZ.js} +3 -3
- package/{chunk-CBHGZRCE.js → chunk-MYOH447Z.js} +1 -1
- package/{chunk-6MPAEODB.js → chunk-NDZOXXIM.js} +17 -3
- package/{chunk-MVJVF4ED.js → chunk-NKPAHRMA.js} +7 -6
- package/{chunk-ZD2BLOY6.js → chunk-O4ZERG3M.js} +3 -3
- package/{chunk-36OMEXXR.js → chunk-OON4OBWI.js} +1 -1
- package/{chunk-SEJ5OS6F.js → chunk-PXYBUFDB.js} +4 -0
- package/{chunk-G47IPDOK.js → chunk-QPY264HO.js} +1 -1
- package/{chunk-TNIX77YM.js → chunk-R5GO3YZP.js} +34 -1
- package/{chunk-EJU23ST5.js → chunk-S72LMV7T.js} +670 -627
- package/{chunk-D4OWHT5Y.js → chunk-SPKLALBU.js} +2 -2
- package/{chunk-FDT27L7S.js → chunk-UCLSOLX4.js} +7 -5
- package/{chunk-B2EGWZJG.js → chunk-UFYBYB26.js} +1 -1
- package/{chunk-3XZKV7QQ.js → chunk-US6MKPE7.js} +1 -1
- package/{chunk-VAZHH6FO.js → chunk-VDEVDGEM.js} +18 -12
- package/{chunk-HXHSTRGH.js → chunk-VYNMQ6HW.js} +0 -27
- package/{chunk-7BSQK2UC.js → chunk-WRCZXJ4N.js} +2 -2
- package/{chunk-H4KACZMG.js → chunk-WTFRBJT5.js} +261 -126
- package/{chunk-QDA4Y5O6.js → chunk-WXFZ4P6O.js} +18 -14
- package/chunk-Y5GCAMGP.js +9 -0
- package/{chunk-SCJD2PNK.js → chunk-YPG7TUQD.js} +3 -3
- package/{chunk-XFKZ3MCV.js → chunk-YTXQ2U2X.js} +221 -65
- package/{chunk-ZEHTARJA.js → chunk-ZBXIKCZ4.js} +38 -92
- package/{chunk-HKT6QXP3.js → chunk-ZEY4NJRE.js} +2 -2
- package/{chunk-HP6O6LTV.js → chunk-ZVQHBIWV.js} +6 -6
- package/{commandRegistry-OUBQIF62.js → commandRegistry-D6JTVYKG.js} +73 -81
- package/{contentThunks-B3FRQGP7.js → contentThunks-DYQO4CTI.js} +14 -13
- package/{createAgentAutomationAction-T2YFJ6MY.js → createAgentAutomationAction-LW26KIBP.js} +14 -13
- package/{createDialogAction-2NFGFBXW.js → createDialogAction-VLLBRD52.js} +15 -14
- package/{createPageAction-LDAVZDN7.js → createPageAction-PDACOLI6.js} +14 -13
- package/{dbSlice-5QGKMQLO.js → dbSlice-DC2J53RC.js} +6 -6
- package/{deleteFile-EW6QNRRT.js → deleteFile-KYWEMNFX.js} +4 -4
- package/{dialogCommands-ZLBEAQHE.js → dialogCommands-F3Y4KCPZ.js} +12 -11
- package/{dialogSlice-64S3J6CP.js → dialogSlice-ERMZYMS6.js} +13 -12
- package/{docCreateCommands-XOG5BBFQ.js → docCreateCommands-YMWZLW64.js} +8 -8
- package/{docDeleteCommands-NCW3BBRX.js → docDeleteCommands-6KJ3ESK4.js} +9 -9
- package/{docReadCommands-OT7X44Y3.js → docReadCommands-YQGFVLWI.js} +8 -8
- package/{docStore-NIP7OO4I.js → docStore-HXKI6W5D.js} +7 -7
- package/{docUpdateCommands-JW7OWW2J.js → docUpdateCommands-QLSGXUEX.js} +8 -8
- package/{handleSendMessageAction-TOKA7ED7.js → handleSendMessageAction-2XCOZPXY.js} +25 -24
- package/index.js +6 -6
- package/{localRuntimeAdapter-EQM6LFYC.js → localRuntimeAdapter-VOFUPXNF.js} +42 -40
- package/{machineCommands-WJ7FZ67T.js → machineCommands-IN5O7CIO.js} +46 -44
- package/{machineWsRunDispatch-BQT4DEA2.js → machineWsRunDispatch-TH3GMSR3.js} +41 -41
- package/{memberThunks-KRV5YXOB.js → memberThunks-2DWKLE6W.js} +7 -7
- package/package.json +1 -1
- package/{profileConfig-ZGOFORWV.js → profileConfig-KN3N2BLF.js} +7 -1
- package/{providerPresetApply-CRZFMQD5.js → providerPresetApply-GSJI4JBJ.js} +1 -1
- package/{providerRegistry-7IS43D3X.js → providerRegistry-TSSTPGWF.js} +1 -1
- package/{read-5KAZHHDM.js → read-L7QEJETH.js} +4 -4
- package/{readDocTool-5QO34OSX.js → readDocTool-QELXV2GW.js} +1 -1
- package/{readlineWorkspace-JHJSU5DS.js → readlineWorkspace-EIEQUTEZ.js} +317 -104
- package/{removeDialogAgentAction-6X63HMI3.js → removeDialogAgentAction-376XSUP2.js} +8 -8
- package/{runAgentClientLoop-5QIGEALK.js → runAgentClientLoop-3KHKKBZI.js} +39 -34
- package/{secretCommands-ZXZRLR3R.js → secretCommands-DNY56NSU.js} +11 -1
- package/{setDialogExtraReferencesAction-4MAYKKYW.js → setDialogExtraReferencesAction-QBDSH63D.js} +7 -7
- package/{setPrimaryDialogAgentAction-EGBAMREH.js → setPrimaryDialogAgentAction-537QFGW3.js} +8 -8
- package/settingThunks-4Z43ZSAT.js +923 -0
- package/{spaceCommands-ZWDPTURU.js → spaceCommands-T5Z4U7HP.js} +8 -8
- package/{streamAgentChatTurn-456DWXNY.js → streamAgentChatTurn-DMXXSEVX.js} +39 -39
- package/{switchDialogAgentAction-YBKTD6DO.js → switchDialogAgentAction-CSO6AKRL.js} +6 -6
- package/{tableCommands-U3QDY4L6.js → tableCommands-LBH3QPPO.js} +1 -1
- package/{toolApiClient-7WSJJJBV.js → toolApiClient-HGNO53TC.js} +2 -2
- package/{tools-IWNXKK4Y.js → tools-RMT7NAMC.js} +29 -28
- package/{updateCommands-NQXAGFM7.js → updateCommands-LXZLG44Y.js} +2 -2
- package/{updateDialogTitleAction-SX53FZWO.js → updateDialogTitleAction-Z4WNUH6Y.js} +14 -13
- package/{workloadLifecycle-36DXRZKU.js → workloadLifecycle-6O6PMISX.js} +2 -2
- package/chunk-W4S6OTSC.js +0 -35
- package/settingThunks-FTDRZNSJ.js +0 -1371
|
@@ -0,0 +1,923 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DEFAULT_USER_PREFERENCE_PROFILE,
|
|
3
|
+
SYSTEM_DEFAULT_AGENT_ID,
|
|
4
|
+
hasOwn,
|
|
5
|
+
normalizeAgentUpdateFieldList,
|
|
6
|
+
normalizeAuthorityHomeServerSetting,
|
|
7
|
+
normalizeDefaultAgentIdSetting,
|
|
8
|
+
normalizePolicyLevelSetting,
|
|
9
|
+
normalizeSystemBuiltinSkills,
|
|
10
|
+
normalizeTonePresetSetting,
|
|
11
|
+
omitKeys,
|
|
12
|
+
resolveDefaultAgentIdSetting
|
|
13
|
+
} from "./chunk-VYNMQ6HW.js";
|
|
14
|
+
import {
|
|
15
|
+
require_react
|
|
16
|
+
} from "./chunk-YDH3FDFQ.js";
|
|
17
|
+
import {
|
|
18
|
+
patch,
|
|
19
|
+
readAndWait,
|
|
20
|
+
toTimestampMs,
|
|
21
|
+
upsert,
|
|
22
|
+
write
|
|
23
|
+
} from "./chunk-ZVQHBIWV.js";
|
|
24
|
+
import "./chunk-3PVYUPXK.js";
|
|
25
|
+
import "./chunk-NDZOXXIM.js";
|
|
26
|
+
import "./chunk-SPKLALBU.js";
|
|
27
|
+
import {
|
|
28
|
+
getRuntimeServerContext
|
|
29
|
+
} from "./chunk-2SGAI64X.js";
|
|
30
|
+
import "./chunk-UEILX4EV.js";
|
|
31
|
+
import {
|
|
32
|
+
createAction,
|
|
33
|
+
createAsyncThunk
|
|
34
|
+
} from "./chunk-WRCZXJ4N.js";
|
|
35
|
+
import {
|
|
36
|
+
fetchFromServer
|
|
37
|
+
} from "./chunk-6Q7UTJKR.js";
|
|
38
|
+
import "./chunk-QQ56R7KS.js";
|
|
39
|
+
import "./chunk-OW765XBU.js";
|
|
40
|
+
import {
|
|
41
|
+
getSessionGenerationForState,
|
|
42
|
+
selectIdentityUserId
|
|
43
|
+
} from "./chunk-PXYBUFDB.js";
|
|
44
|
+
import "./chunk-D2MDMY2M.js";
|
|
45
|
+
import {
|
|
46
|
+
DEFAULT_SYSTEM_AGENT_CAPABILITIES
|
|
47
|
+
} from "./chunk-EUGTFFO6.js";
|
|
48
|
+
import "./chunk-Y6ORVLSS.js";
|
|
49
|
+
import {
|
|
50
|
+
asRecordOrEmpty
|
|
51
|
+
} from "./chunk-KX6YBIHG.js";
|
|
52
|
+
import "./chunk-7DPNBQSV.js";
|
|
53
|
+
import "./chunk-LOEO7LRC.js";
|
|
54
|
+
import "./chunk-M2EJHDJP.js";
|
|
55
|
+
import {
|
|
56
|
+
createUserKey,
|
|
57
|
+
createUserPreferenceKey,
|
|
58
|
+
ulid
|
|
59
|
+
} from "./chunk-5EMSBTQ6.js";
|
|
60
|
+
import "./chunk-I42VC5KR.js";
|
|
61
|
+
import "./chunk-U6VC4MU4.js";
|
|
62
|
+
import "./chunk-WWC7I6TA.js";
|
|
63
|
+
import "./chunk-KUG52IAP.js";
|
|
64
|
+
import "./chunk-3EUW3WEO.js";
|
|
65
|
+
import "./chunk-LCBAMY2M.js";
|
|
66
|
+
import "./chunk-4SN6J65J.js";
|
|
67
|
+
import "./chunk-CF7PE763.js";
|
|
68
|
+
import "./chunk-G3SUCT4W.js";
|
|
69
|
+
import "./chunk-QSJ3HFEF.js";
|
|
70
|
+
import {
|
|
71
|
+
__toESM
|
|
72
|
+
} from "./chunk-4VNS5WPM.js";
|
|
73
|
+
|
|
74
|
+
// packages/database/userPreferenceRegister.ts
|
|
75
|
+
var USER_PREFERENCE_NAMES = {
|
|
76
|
+
AUTHORITY_HOME: "authority_home",
|
|
77
|
+
DEFAULT_AGENT: "agent_default"
|
|
78
|
+
};
|
|
79
|
+
var nextRegisterUpdatedAt = (previousRecord) => {
|
|
80
|
+
const previousTimestamp = Math.max(
|
|
81
|
+
toTimestampMs(previousRecord?.updatedAt),
|
|
82
|
+
toTimestampMs(previousRecord?.createdAt)
|
|
83
|
+
);
|
|
84
|
+
return Math.max(Date.now(), previousTimestamp + 1);
|
|
85
|
+
};
|
|
86
|
+
var buildUserPreferenceRegisterRecord = ({
|
|
87
|
+
userId,
|
|
88
|
+
preferenceName,
|
|
89
|
+
value,
|
|
90
|
+
previousRecord
|
|
91
|
+
}) => {
|
|
92
|
+
const updatedAt = nextRegisterUpdatedAt(previousRecord ?? void 0);
|
|
93
|
+
return {
|
|
94
|
+
type: "setting" /* SETTING */,
|
|
95
|
+
registerType: "user_preference",
|
|
96
|
+
preferenceName,
|
|
97
|
+
schemaVersion: 1,
|
|
98
|
+
userId,
|
|
99
|
+
value,
|
|
100
|
+
opId: ulid(),
|
|
101
|
+
createdAt: toTimestampMs(previousRecord?.createdAt) || updatedAt,
|
|
102
|
+
updatedAt
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
var readUserPreferenceRegisterValue = (record, preferenceName) => {
|
|
106
|
+
if (!record || typeof record !== "object") return void 0;
|
|
107
|
+
if (record.registerType !== "user_preference") return void 0;
|
|
108
|
+
if (record.preferenceName !== preferenceName) return void 0;
|
|
109
|
+
if (!("value" in record)) return void 0;
|
|
110
|
+
return record.value;
|
|
111
|
+
};
|
|
112
|
+
var buildDefaultAgentPreferenceRegisterRecord = ({
|
|
113
|
+
userId,
|
|
114
|
+
defaultAgentId,
|
|
115
|
+
previousRecord
|
|
116
|
+
}) => buildUserPreferenceRegisterRecord({
|
|
117
|
+
userId,
|
|
118
|
+
preferenceName: USER_PREFERENCE_NAMES.DEFAULT_AGENT,
|
|
119
|
+
value: defaultAgentId,
|
|
120
|
+
previousRecord
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// packages/app/settings/settingActions.ts
|
|
124
|
+
var updateSettingsState = createAction(
|
|
125
|
+
"settings/_updateSettingsState"
|
|
126
|
+
);
|
|
127
|
+
var bumpLocalIntentEpoch = createAction("settings/_bumpLocalIntentEpoch");
|
|
128
|
+
var recordSettingsWriteFailure = createAction(
|
|
129
|
+
"settings/_recordSettingsWriteFailure"
|
|
130
|
+
);
|
|
131
|
+
var recordServerAuthorityEcho = createAction(
|
|
132
|
+
"settings/_recordServerAuthorityEcho"
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
// packages/app/settings/accountSettingsWriteQueue.ts
|
|
136
|
+
var queues = /* @__PURE__ */ new WeakMap();
|
|
137
|
+
function enqueueAccountSettingsWrite(getState, accountId, write2) {
|
|
138
|
+
let byAccount = queues.get(getState);
|
|
139
|
+
if (!byAccount) {
|
|
140
|
+
byAccount = /* @__PURE__ */ new Map();
|
|
141
|
+
queues.set(getState, byAccount);
|
|
142
|
+
}
|
|
143
|
+
const previous = byAccount.get(accountId) ?? Promise.resolve();
|
|
144
|
+
const result = previous.catch(() => void 0).then(write2);
|
|
145
|
+
const tail = result.then(() => void 0, () => void 0);
|
|
146
|
+
byAccount.set(accountId, tail);
|
|
147
|
+
void tail.then(() => {
|
|
148
|
+
if (byAccount?.get(accountId) === tail) byAccount.delete(accountId);
|
|
149
|
+
});
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// packages/app/settings/accountChatDisplayOwner.ts
|
|
154
|
+
var import_react = __toESM(require_react());
|
|
155
|
+
var DEFAULT_ACCOUNT_CHAT_DISPLAY_PREFERENCES = Object.freeze({
|
|
156
|
+
showThinking: true,
|
|
157
|
+
showScrollToTopButton: false,
|
|
158
|
+
showScrollToBottomButton: false
|
|
159
|
+
});
|
|
160
|
+
var createAccountChatDisplayOwner = () => {
|
|
161
|
+
let accountId = null;
|
|
162
|
+
let snapshot = DEFAULT_ACCOUNT_CHAT_DISPLAY_PREFERENCES;
|
|
163
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
164
|
+
const emit = () => listeners.forEach((listener) => listener());
|
|
165
|
+
return {
|
|
166
|
+
getAccountId: () => accountId,
|
|
167
|
+
getSnapshot: () => snapshot,
|
|
168
|
+
subscribe: (listener) => {
|
|
169
|
+
listeners.add(listener);
|
|
170
|
+
return () => {
|
|
171
|
+
listeners.delete(listener);
|
|
172
|
+
};
|
|
173
|
+
},
|
|
174
|
+
setAccount: (nextAccountId) => {
|
|
175
|
+
if (accountId === nextAccountId) return;
|
|
176
|
+
accountId = nextAccountId;
|
|
177
|
+
snapshot = DEFAULT_ACCOUNT_CHAT_DISPLAY_PREFERENCES;
|
|
178
|
+
emit();
|
|
179
|
+
},
|
|
180
|
+
updateForAccount: (expectedAccountId, changes) => {
|
|
181
|
+
if (!expectedAccountId || expectedAccountId !== accountId) return false;
|
|
182
|
+
const next = { ...snapshot, ...changes };
|
|
183
|
+
if (next.showThinking === snapshot.showThinking && next.showScrollToTopButton === snapshot.showScrollToTopButton && next.showScrollToBottomButton === snapshot.showScrollToBottomButton) return true;
|
|
184
|
+
snapshot = Object.freeze(next);
|
|
185
|
+
emit();
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
var owners = /* @__PURE__ */ new WeakMap();
|
|
191
|
+
function getAccountChatDisplayOwner(getState) {
|
|
192
|
+
let owner = owners.get(getState);
|
|
193
|
+
if (!owner) {
|
|
194
|
+
owner = createAccountChatDisplayOwner();
|
|
195
|
+
owners.set(getState, owner);
|
|
196
|
+
}
|
|
197
|
+
return owner;
|
|
198
|
+
}
|
|
199
|
+
function pickAccountChatDisplayPreferences(value) {
|
|
200
|
+
const result = {};
|
|
201
|
+
for (const key of ["showThinking", "showScrollToTopButton", "showScrollToBottomButton"]) {
|
|
202
|
+
if (typeof value[key] === "boolean") result[key] = value[key];
|
|
203
|
+
}
|
|
204
|
+
return result;
|
|
205
|
+
}
|
|
206
|
+
var omitAccountChatDisplayPreferences = (value) => {
|
|
207
|
+
const { showThinking: _thinking, showScrollToTopButton: _top, showScrollToBottomButton: _bottom, ...rest } = value;
|
|
208
|
+
return rest;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// packages/app/settings/dbActionThunks.ts
|
|
212
|
+
var getDefaultSettingDbActionThunks = () => ({
|
|
213
|
+
readAndWait,
|
|
214
|
+
patch,
|
|
215
|
+
upsert,
|
|
216
|
+
write
|
|
217
|
+
});
|
|
218
|
+
var settingDbActionThunksOverrideKey = Symbol.for(
|
|
219
|
+
"bun-nolo.app.settings.dbActionThunksOverride"
|
|
220
|
+
);
|
|
221
|
+
var getSettingDbActionThunks = () => {
|
|
222
|
+
const globalOverride = globalThis[settingDbActionThunksOverrideKey];
|
|
223
|
+
return globalOverride ?? getDefaultSettingDbActionThunks();
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
// packages/app/settings/settingsRecord.ts
|
|
227
|
+
var SETTINGS_RECORD_SCHEMA_VERSION = 1;
|
|
228
|
+
var withSettingsRecordSchema = (changes) => ({
|
|
229
|
+
...changes,
|
|
230
|
+
schemaVersion: SETTINGS_RECORD_SCHEMA_VERSION
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// packages/app/settings/settingPersistence.ts
|
|
234
|
+
var normalizeSettingChanges = (changes) => {
|
|
235
|
+
let normalizedChanges = omitKeys(changes, [
|
|
236
|
+
"preferredAnimationSet",
|
|
237
|
+
"createMenuOpenCount",
|
|
238
|
+
// 本地意图世代只活在 redux 状态里:既不能从服务端 record 写回,也不能写云。
|
|
239
|
+
"localIntentEpoch",
|
|
240
|
+
// 权威回显世代同理:纯本地世代标记,不入云端 record、不被远端回灌。
|
|
241
|
+
"serverAuthorityEchoSeq",
|
|
242
|
+
// 写失败状态同样是纯本地 observability:绝不进入云端 settings record。
|
|
243
|
+
"lastWriteFailure",
|
|
244
|
+
// Retired device appearance is never accepted by Redux, including legacy callers.
|
|
245
|
+
"themeName",
|
|
246
|
+
"themeMode",
|
|
247
|
+
"isDark",
|
|
248
|
+
"density",
|
|
249
|
+
"fontPreset"
|
|
250
|
+
]);
|
|
251
|
+
if (hasOwn(normalizedChanges, "defaultAgentId")) {
|
|
252
|
+
normalizedChanges = {
|
|
253
|
+
...normalizedChanges,
|
|
254
|
+
defaultAgentId: normalizeDefaultAgentIdSetting(
|
|
255
|
+
normalizedChanges.defaultAgentId
|
|
256
|
+
)
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
if (hasOwn(normalizedChanges, "defaultSpaceId")) {
|
|
260
|
+
normalizedChanges = omitKeys(normalizedChanges, [
|
|
261
|
+
"defaultSpaceId"
|
|
262
|
+
]);
|
|
263
|
+
}
|
|
264
|
+
if (hasOwn(normalizedChanges, "userTonePreset")) {
|
|
265
|
+
normalizedChanges = {
|
|
266
|
+
...normalizedChanges,
|
|
267
|
+
userTonePreset: normalizeTonePresetSetting(
|
|
268
|
+
normalizedChanges.userTonePreset
|
|
269
|
+
)
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
if (hasOwn(normalizedChanges, "knowledgeCaptureLevel")) {
|
|
273
|
+
normalizedChanges = {
|
|
274
|
+
...normalizedChanges,
|
|
275
|
+
knowledgeCaptureLevel: normalizePolicyLevelSetting(
|
|
276
|
+
normalizedChanges.knowledgeCaptureLevel,
|
|
277
|
+
DEFAULT_USER_PREFERENCE_PROFILE.knowledgeCaptureLevel
|
|
278
|
+
)
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
if (hasOwn(normalizedChanges, "spaceContextLevel")) {
|
|
282
|
+
normalizedChanges = {
|
|
283
|
+
...normalizedChanges,
|
|
284
|
+
spaceContextLevel: normalizePolicyLevelSetting(
|
|
285
|
+
normalizedChanges.spaceContextLevel,
|
|
286
|
+
DEFAULT_USER_PREFERENCE_PROFILE.spaceContextLevel
|
|
287
|
+
)
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
if (hasOwn(normalizedChanges, "autoApproveSelfUpdateFields")) {
|
|
291
|
+
normalizedChanges = {
|
|
292
|
+
...normalizedChanges,
|
|
293
|
+
autoApproveSelfUpdateFields: normalizeAgentUpdateFieldList(
|
|
294
|
+
normalizedChanges.autoApproveSelfUpdateFields
|
|
295
|
+
)
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
if (hasOwn(normalizedChanges, "systemBuiltinSkills")) {
|
|
299
|
+
normalizedChanges = {
|
|
300
|
+
...normalizedChanges,
|
|
301
|
+
systemBuiltinSkills: normalizeSystemBuiltinSkills(
|
|
302
|
+
normalizedChanges.systemBuiltinSkills,
|
|
303
|
+
DEFAULT_SYSTEM_AGENT_CAPABILITIES
|
|
304
|
+
)
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
return normalizedChanges;
|
|
308
|
+
};
|
|
309
|
+
var LOCAL_APPEARANCE_KEY_NAMES = [
|
|
310
|
+
"themeName",
|
|
311
|
+
"themeMode",
|
|
312
|
+
"isDark",
|
|
313
|
+
"density",
|
|
314
|
+
"fontPreset"
|
|
315
|
+
];
|
|
316
|
+
var GUEST_UPDATABLE_KEY_NAMES = [
|
|
317
|
+
"sidebarWidth"
|
|
318
|
+
];
|
|
319
|
+
var LOCAL_FIRST_APPEARANCE_KEYS = Object.freeze(
|
|
320
|
+
Object.fromEntries(
|
|
321
|
+
LOCAL_APPEARANCE_KEY_NAMES.map((key) => [key, true])
|
|
322
|
+
)
|
|
323
|
+
);
|
|
324
|
+
var GUEST_UPDATABLE_KEYS = Object.freeze(
|
|
325
|
+
Object.fromEntries(
|
|
326
|
+
GUEST_UPDATABLE_KEY_NAMES.map((key) => [key, true])
|
|
327
|
+
)
|
|
328
|
+
);
|
|
329
|
+
var isGuestUpdatableKey = (key) => key in GUEST_UPDATABLE_KEYS;
|
|
330
|
+
var isLocalFirstAppearanceChange = (changes) => {
|
|
331
|
+
const keys = Object.keys(changes);
|
|
332
|
+
if (keys.length === 0) return false;
|
|
333
|
+
return keys.every(
|
|
334
|
+
(key) => isGuestUpdatableKey(key)
|
|
335
|
+
);
|
|
336
|
+
};
|
|
337
|
+
var stripRegisterBackedFieldsFromSettingsWrite = (changes) => {
|
|
338
|
+
return omitKeys(changes, [
|
|
339
|
+
"autoApproveCredits",
|
|
340
|
+
"defaultSpaceId",
|
|
341
|
+
"userAuthorityRegistry",
|
|
342
|
+
"preferredAnimationSet",
|
|
343
|
+
"createMenuOpenCount",
|
|
344
|
+
...LOCAL_APPEARANCE_KEY_NAMES
|
|
345
|
+
]);
|
|
346
|
+
};
|
|
347
|
+
var sanitizeStoredSettingsRecord = (settingsRecord) => {
|
|
348
|
+
if (!settingsRecord || typeof settingsRecord !== "object") {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
const record = settingsRecord;
|
|
352
|
+
const sanitizedSettings = omitKeys(record, [
|
|
353
|
+
"autoApproveCredits",
|
|
354
|
+
"defaultSpaceId",
|
|
355
|
+
"schemaVersion",
|
|
356
|
+
"preferredAnimationSet",
|
|
357
|
+
...LOCAL_APPEARANCE_KEY_NAMES
|
|
358
|
+
]);
|
|
359
|
+
return Object.keys(sanitizedSettings).length > 0 ? sanitizedSettings : null;
|
|
360
|
+
};
|
|
361
|
+
var hydrateStoredSettings = ({
|
|
362
|
+
userId,
|
|
363
|
+
settingsRecord,
|
|
364
|
+
authorityHomeServer
|
|
365
|
+
}) => {
|
|
366
|
+
const record = settingsRecord ?? {};
|
|
367
|
+
const resolvedDefaultAgentId = normalizeDefaultAgentIdSetting(record.defaultAgentId) ?? SYSTEM_DEFAULT_AGENT_ID;
|
|
368
|
+
const baseSettings = sanitizeStoredSettingsRecord(settingsRecord) ?? {};
|
|
369
|
+
const normalizedAuthorityHome = normalizeAuthorityHomeServerSetting(authorityHomeServer);
|
|
370
|
+
const existingRegistry = asRecordOrEmpty(
|
|
371
|
+
baseSettings.userAuthorityRegistry
|
|
372
|
+
);
|
|
373
|
+
const userAuthorityRegistry = userId && normalizedAuthorityHome ? { ...existingRegistry, [userId]: normalizedAuthorityHome } : existingRegistry;
|
|
374
|
+
const userAuthorityRegistryIsEmpty = Object.keys(userAuthorityRegistry).length === 0;
|
|
375
|
+
const hydratedSettings = {
|
|
376
|
+
...baseSettings,
|
|
377
|
+
// 服务端独占字段:只读回显(缺失时沿用初始值 0,非法值按 0)
|
|
378
|
+
...hasOwn(record, "autoApproveCredits") ? { autoApproveCredits: typeof record.autoApproveCredits === "number" && Number.isFinite(record.autoApproveCredits) && record.autoApproveCredits >= 0 ? record.autoApproveCredits : 0 } : {},
|
|
379
|
+
...userAuthorityRegistryIsEmpty ? {} : { userAuthorityRegistry },
|
|
380
|
+
defaultAgentId: resolvedDefaultAgentId
|
|
381
|
+
};
|
|
382
|
+
return Object.keys(hydratedSettings).length > 0 ? hydratedSettings : null;
|
|
383
|
+
};
|
|
384
|
+
var SERVER_AUTHORITATIVE_SETTINGS_KEYS = [
|
|
385
|
+
"autoApproveCredits",
|
|
386
|
+
"userAuthorityRegistry"
|
|
387
|
+
];
|
|
388
|
+
var pickServerAuthoritativeSettings = (hydrated) => {
|
|
389
|
+
const picked = {};
|
|
390
|
+
for (const key of SERVER_AUTHORITATIVE_SETTINGS_KEYS) {
|
|
391
|
+
if (hasOwn(hydrated, key)) {
|
|
392
|
+
picked[key] = hydrated[key];
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return picked;
|
|
396
|
+
};
|
|
397
|
+
var buildSettingsPersistencePlan = ({
|
|
398
|
+
userId,
|
|
399
|
+
currentSettings,
|
|
400
|
+
changes,
|
|
401
|
+
previousDefaultAgentRecord
|
|
402
|
+
}) => {
|
|
403
|
+
const normalizedChanges = normalizeSettingChanges(changes);
|
|
404
|
+
const persistedChanges = stripRegisterBackedFieldsFromSettingsWrite(normalizedChanges);
|
|
405
|
+
const previousDefaultAgentId = normalizeDefaultAgentIdSetting(currentSettings.defaultAgentId) ?? SYSTEM_DEFAULT_AGENT_ID;
|
|
406
|
+
const nextDefaultAgentId = normalizeDefaultAgentIdSetting(normalizedChanges.defaultAgentId) ?? null;
|
|
407
|
+
const previousDefaultAgentValue = readUserPreferenceRegisterValue(
|
|
408
|
+
previousDefaultAgentRecord,
|
|
409
|
+
USER_PREFERENCE_NAMES.DEFAULT_AGENT
|
|
410
|
+
) ?? null;
|
|
411
|
+
const defaultAgentRegisterWrite = hasOwn(normalizedChanges, "defaultAgentId") && previousDefaultAgentId !== (nextDefaultAgentId ?? SYSTEM_DEFAULT_AGENT_ID) && (!previousDefaultAgentRecord || previousDefaultAgentValue !== nextDefaultAgentId) ? {
|
|
412
|
+
customKey: createUserPreferenceKey.defaultAgent(userId),
|
|
413
|
+
data: buildDefaultAgentPreferenceRegisterRecord({
|
|
414
|
+
userId,
|
|
415
|
+
defaultAgentId: nextDefaultAgentId,
|
|
416
|
+
previousRecord: previousDefaultAgentRecord
|
|
417
|
+
})
|
|
418
|
+
} : null;
|
|
419
|
+
const settingsPatch = Object.keys(persistedChanges).length > 0 ? {
|
|
420
|
+
dbKey: createUserKey.settings(userId),
|
|
421
|
+
changes: withSettingsRecordSchema(
|
|
422
|
+
persistedChanges
|
|
423
|
+
)
|
|
424
|
+
} : null;
|
|
425
|
+
return {
|
|
426
|
+
normalizedChanges,
|
|
427
|
+
defaultAgentRegisterWrite,
|
|
428
|
+
settingsPatch
|
|
429
|
+
};
|
|
430
|
+
};
|
|
431
|
+
var getCachedDefaultAgentRegisterRecord = (getState, registerKey) => {
|
|
432
|
+
const record = getState().db.entities[registerKey];
|
|
433
|
+
if (!record || typeof record !== "object") return null;
|
|
434
|
+
return record;
|
|
435
|
+
};
|
|
436
|
+
var persistDefaultAgentRegister = async (dispatch, getState, userId, value) => {
|
|
437
|
+
const registerKey = createUserPreferenceKey.defaultAgent(userId);
|
|
438
|
+
let previousRecord = getCachedDefaultAgentRegisterRecord(getState, registerKey);
|
|
439
|
+
if (!previousRecord) {
|
|
440
|
+
previousRecord = await dispatch(
|
|
441
|
+
getSettingDbActionThunks().readAndWait(registerKey)
|
|
442
|
+
).unwrap().catch(() => null);
|
|
443
|
+
}
|
|
444
|
+
const previousValue = readUserPreferenceRegisterValue(
|
|
445
|
+
previousRecord,
|
|
446
|
+
USER_PREFERENCE_NAMES.DEFAULT_AGENT
|
|
447
|
+
) ?? null;
|
|
448
|
+
if (previousRecord && previousValue === value) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
await dispatch(
|
|
452
|
+
getSettingDbActionThunks().write({
|
|
453
|
+
customKey: registerKey,
|
|
454
|
+
data: buildDefaultAgentPreferenceRegisterRecord({
|
|
455
|
+
userId,
|
|
456
|
+
defaultAgentId: value,
|
|
457
|
+
previousRecord
|
|
458
|
+
})
|
|
459
|
+
})
|
|
460
|
+
).unwrap();
|
|
461
|
+
};
|
|
462
|
+
|
|
463
|
+
// packages/app/settings/settingsWriteRetry.ts
|
|
464
|
+
var SETTINGS_WRITE_RETRY_BACKOFF_MS = 200;
|
|
465
|
+
var SETTINGS_RECONCILE_DEADLINE_MS = 3e3;
|
|
466
|
+
var delaySettingsWriteRetry = (ms) => new Promise((resolve) => {
|
|
467
|
+
setTimeout(resolve, ms);
|
|
468
|
+
});
|
|
469
|
+
var readLocalIntentEpoch = (getState) => {
|
|
470
|
+
const value = getState()?.settings?.localIntentEpoch;
|
|
471
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
472
|
+
};
|
|
473
|
+
var SettingsWriteSupersededError = class extends Error {
|
|
474
|
+
constructor(message = "Settings write superseded by a newer local intent.") {
|
|
475
|
+
super(message);
|
|
476
|
+
this.name = "SettingsWriteSupersededError";
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
var isSettingsWriteSupersededError = (error) => error instanceof SettingsWriteSupersededError;
|
|
480
|
+
var reconcileDeadlineOverride = null;
|
|
481
|
+
var reconcileDeadlineMs = () => reconcileDeadlineOverride ?? SETTINGS_RECONCILE_DEADLINE_MS;
|
|
482
|
+
var readSettingsAuthorityServer = (getState, accountId) => {
|
|
483
|
+
const registry = getState()?.settings?.userAuthorityRegistry;
|
|
484
|
+
if (!registry || typeof registry !== "object") return null;
|
|
485
|
+
const value = registry[accountId];
|
|
486
|
+
if (typeof value !== "string") return null;
|
|
487
|
+
const trimmed = value.trim();
|
|
488
|
+
return trimmed === "" ? null : trimmed;
|
|
489
|
+
};
|
|
490
|
+
var readAuthoritativeSettingsRecord = async (dbKey, getState, accountId) => {
|
|
491
|
+
const authorityServer = readSettingsAuthorityServer(getState, accountId);
|
|
492
|
+
if (!authorityServer) return null;
|
|
493
|
+
let token;
|
|
494
|
+
try {
|
|
495
|
+
token = getRuntimeServerContext(getState()).currentToken || void 0;
|
|
496
|
+
} catch {
|
|
497
|
+
token = void 0;
|
|
498
|
+
}
|
|
499
|
+
const controller = new AbortController();
|
|
500
|
+
const timer = setTimeout(() => controller.abort(), reconcileDeadlineMs());
|
|
501
|
+
try {
|
|
502
|
+
const remote = await fetchFromServer(
|
|
503
|
+
authorityServer,
|
|
504
|
+
dbKey,
|
|
505
|
+
token,
|
|
506
|
+
controller.signal
|
|
507
|
+
);
|
|
508
|
+
if (remote && typeof remote === "object" && Object.keys(remote).length > 0) {
|
|
509
|
+
return remote;
|
|
510
|
+
}
|
|
511
|
+
return null;
|
|
512
|
+
} catch {
|
|
513
|
+
return null;
|
|
514
|
+
} finally {
|
|
515
|
+
clearTimeout(timer);
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
var authorityReaderOverride = null;
|
|
519
|
+
var readSettingsAuthorityRecord = async (dbKey, getState, accountId) => {
|
|
520
|
+
const reader = authorityReaderOverride ?? readAuthoritativeSettingsRecord;
|
|
521
|
+
const read = Promise.resolve().then(() => reader(dbKey, getState, accountId)).catch(() => null);
|
|
522
|
+
const deadline = delaySettingsWriteRetry(reconcileDeadlineMs()).then(
|
|
523
|
+
() => null
|
|
524
|
+
);
|
|
525
|
+
return await Promise.race([read, deadline]);
|
|
526
|
+
};
|
|
527
|
+
var stableValueKey = (value) => {
|
|
528
|
+
if (value === void 0) return "undefined";
|
|
529
|
+
if (value === null || typeof value !== "object") {
|
|
530
|
+
return JSON.stringify(value) ?? "undefined";
|
|
531
|
+
}
|
|
532
|
+
if (Array.isArray(value)) {
|
|
533
|
+
return `[${value.map(stableValueKey).join(",")}]`;
|
|
534
|
+
}
|
|
535
|
+
const record = value;
|
|
536
|
+
const entries = Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableValueKey(record[key])}`);
|
|
537
|
+
return `{${entries.join(",")}}`;
|
|
538
|
+
};
|
|
539
|
+
var isSameSettingValue = (a, b) => stableValueKey(a) === stableValueKey(b);
|
|
540
|
+
var resolveSettingsWriteFailureAfterSuccess = ({
|
|
541
|
+
failure,
|
|
542
|
+
accountId,
|
|
543
|
+
intentKeys,
|
|
544
|
+
persistedKeys
|
|
545
|
+
}) => {
|
|
546
|
+
if (!failure) return null;
|
|
547
|
+
if (failure.accountId !== accountId) return failure;
|
|
548
|
+
const covered = /* @__PURE__ */ new Set([...intentKeys, ...persistedKeys]);
|
|
549
|
+
const remainingKeys = failure.keys.filter((key) => !covered.has(key));
|
|
550
|
+
if (remainingKeys.length === 0) return null;
|
|
551
|
+
return {
|
|
552
|
+
...failure,
|
|
553
|
+
keys: remainingKeys,
|
|
554
|
+
unresolvedKeys: failure.unresolvedKeys.filter((key) => !covered.has(key))
|
|
555
|
+
};
|
|
556
|
+
};
|
|
557
|
+
var describeSettingsWriteFailure = async ({
|
|
558
|
+
getState,
|
|
559
|
+
accountId,
|
|
560
|
+
intentEpoch,
|
|
561
|
+
intentKeys,
|
|
562
|
+
persistedKeys,
|
|
563
|
+
at
|
|
564
|
+
}) => {
|
|
565
|
+
const base = {
|
|
566
|
+
accountId,
|
|
567
|
+
keys: [...intentKeys].sort(),
|
|
568
|
+
at,
|
|
569
|
+
reconciliation: "not-attempted",
|
|
570
|
+
unresolvedKeys: [...persistedKeys].sort()
|
|
571
|
+
};
|
|
572
|
+
if (readLocalIntentEpoch(getState) !== intentEpoch) return base;
|
|
573
|
+
const remoteRecord = await readSettingsAuthorityRecord(
|
|
574
|
+
createUserKey.settings(accountId),
|
|
575
|
+
getState,
|
|
576
|
+
accountId
|
|
577
|
+
);
|
|
578
|
+
if (readLocalIntentEpoch(getState) !== intentEpoch) return base;
|
|
579
|
+
const serverRecord = sanitizeStoredSettingsRecord(remoteRecord);
|
|
580
|
+
if (!serverRecord) {
|
|
581
|
+
return {
|
|
582
|
+
...base,
|
|
583
|
+
reconciliation: "unavailable"
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
const localSettings = getState()?.settings ?? {};
|
|
587
|
+
const owner = getAccountChatDisplayOwner(getState);
|
|
588
|
+
const localValues = owner.getAccountId() === accountId ? { ...localSettings, ...owner.getSnapshot() } : localSettings;
|
|
589
|
+
const unresolvedKeys = persistedKeys.filter((key) => !isSameSettingValue(localValues[key], serverRecord[key])).sort();
|
|
590
|
+
return {
|
|
591
|
+
...base,
|
|
592
|
+
reconciliation: unresolvedKeys.length === 0 ? "matched" : "mismatched",
|
|
593
|
+
unresolvedKeys
|
|
594
|
+
};
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
// packages/app/settings/settingThunks.ts
|
|
598
|
+
var readServerAuthorityEchoSeq = (getState) => {
|
|
599
|
+
const value = getState()?.settings?.serverAuthorityEchoSeq;
|
|
600
|
+
return typeof value === "number" && Number.isFinite(value) ? value : 0;
|
|
601
|
+
};
|
|
602
|
+
var latestChatHydrations = /* @__PURE__ */ new WeakMap();
|
|
603
|
+
var getSettings = createAsyncThunk("settings/getSettings", async (_, { dispatch, getState }) => {
|
|
604
|
+
const userId = selectIdentityUserId(getState());
|
|
605
|
+
if (!userId) return null;
|
|
606
|
+
const session = getSessionGenerationForState(getState());
|
|
607
|
+
const hydration = {};
|
|
608
|
+
latestChatHydrations.set(getState, hydration);
|
|
609
|
+
const startLocalIntentEpoch = readLocalIntentEpoch(getState);
|
|
610
|
+
const startAuthorityEchoSeq = readServerAuthorityEchoSeq(getState);
|
|
611
|
+
const settingsKey = createUserKey.settings(userId);
|
|
612
|
+
const authorityHomeKey = createUserPreferenceKey.authorityHome(userId);
|
|
613
|
+
const [settingsRecord, authorityHomeRecord] = await Promise.all([
|
|
614
|
+
dispatch(getSettingDbActionThunks().readAndWait(settingsKey)).unwrap().catch(() => null),
|
|
615
|
+
dispatch(getSettingDbActionThunks().readAndWait(authorityHomeKey)).unwrap().catch(() => null)
|
|
616
|
+
]);
|
|
617
|
+
if (selectIdentityUserId(getState()) !== userId || getSessionGenerationForState(getState()) !== session || latestChatHydrations.get(getState) !== hydration) return null;
|
|
618
|
+
const authorityHomeServer = readUserPreferenceRegisterValue(
|
|
619
|
+
authorityHomeRecord,
|
|
620
|
+
USER_PREFERENCE_NAMES.AUTHORITY_HOME
|
|
621
|
+
) ?? null;
|
|
622
|
+
const hydrated = hydrateStoredSettings({
|
|
623
|
+
userId,
|
|
624
|
+
settingsRecord,
|
|
625
|
+
authorityHomeServer
|
|
626
|
+
});
|
|
627
|
+
if (hydrated) {
|
|
628
|
+
const normalizedPayload = normalizeSettingChanges(
|
|
629
|
+
hydrated
|
|
630
|
+
);
|
|
631
|
+
const { currentServer: _ignored, ...settingsToApply } = normalizedPayload;
|
|
632
|
+
if (selectIdentityUserId(getState()) !== userId || getSessionGenerationForState(getState()) !== session || latestChatHydrations.get(getState) !== hydration) return null;
|
|
633
|
+
const intentChanged = readLocalIntentEpoch(getState) !== startLocalIntentEpoch;
|
|
634
|
+
const echoChanged = readServerAuthorityEchoSeq(getState) !== startAuthorityEchoSeq;
|
|
635
|
+
const authoritative = pickServerAuthoritativeSettings(hydrated);
|
|
636
|
+
const {
|
|
637
|
+
autoApproveCredits: _ignoredCredits,
|
|
638
|
+
userAuthorityRegistry: _ignoredRegistry,
|
|
639
|
+
...preferenceFields
|
|
640
|
+
} = settingsToApply;
|
|
641
|
+
const applied = {};
|
|
642
|
+
if (!intentChanged) Object.assign(applied, preferenceFields);
|
|
643
|
+
if (!echoChanged && hasOwn(authoritative, "autoApproveCredits")) {
|
|
644
|
+
applied.autoApproveCredits = authoritative.autoApproveCredits;
|
|
645
|
+
}
|
|
646
|
+
if (hasOwn(authoritative, "userAuthorityRegistry")) {
|
|
647
|
+
applied.userAuthorityRegistry = authoritative.userAuthorityRegistry;
|
|
648
|
+
}
|
|
649
|
+
if (intentChanged) {
|
|
650
|
+
if (Object.keys(applied).length > 0) {
|
|
651
|
+
dispatch(updateSettingsState(applied));
|
|
652
|
+
}
|
|
653
|
+
return null;
|
|
654
|
+
}
|
|
655
|
+
const owner = getAccountChatDisplayOwner(getState);
|
|
656
|
+
owner.setAccount(userId);
|
|
657
|
+
owner.updateForAccount(userId, pickAccountChatDisplayPreferences(preferenceFields));
|
|
658
|
+
dispatch(updateSettingsState(omitAccountChatDisplayPreferences(applied)));
|
|
659
|
+
}
|
|
660
|
+
return hydrated;
|
|
661
|
+
});
|
|
662
|
+
var persistSettingsChanges = createAsyncThunk("settings/persistSettingsChanges", async (changes, { dispatch, getState }) => {
|
|
663
|
+
const session = getSessionGenerationForState(getState());
|
|
664
|
+
const currentSettings = getState().settings;
|
|
665
|
+
const normalizedChanges = normalizeSettingChanges(changes);
|
|
666
|
+
const previousDefaultAgentId = normalizeDefaultAgentIdSetting(currentSettings.defaultAgentId) ?? SYSTEM_DEFAULT_AGENT_ID;
|
|
667
|
+
const userId = selectIdentityUserId(getState());
|
|
668
|
+
if (!userId) {
|
|
669
|
+
const hasAppearanceChanges = Object.keys(normalizedChanges).length > 0;
|
|
670
|
+
if (hasAppearanceChanges) {
|
|
671
|
+
if (!isLocalFirstAppearanceChange(normalizedChanges)) {
|
|
672
|
+
throw new Error("User not found for persisting settings.");
|
|
673
|
+
}
|
|
674
|
+
} else {
|
|
675
|
+
throw new Error("User not found for persisting settings.");
|
|
676
|
+
}
|
|
677
|
+
dispatch(bumpLocalIntentEpoch());
|
|
678
|
+
dispatch(updateSettingsState(normalizedChanges));
|
|
679
|
+
return normalizedChanges;
|
|
680
|
+
}
|
|
681
|
+
const persistencePlan = buildSettingsPersistencePlan({
|
|
682
|
+
userId,
|
|
683
|
+
currentSettings,
|
|
684
|
+
changes: normalizedChanges,
|
|
685
|
+
previousDefaultAgentRecord: null
|
|
686
|
+
});
|
|
687
|
+
if (selectIdentityUserId(getState()) !== userId) return {};
|
|
688
|
+
const owner = getAccountChatDisplayOwner(getState);
|
|
689
|
+
dispatch(bumpLocalIntentEpoch());
|
|
690
|
+
const intentEpoch = readLocalIntentEpoch(getState);
|
|
691
|
+
owner.setAccount(userId);
|
|
692
|
+
owner.updateForAccount(userId, pickAccountChatDisplayPreferences(persistencePlan.normalizedChanges));
|
|
693
|
+
dispatch(updateSettingsState(omitAccountChatDisplayPreferences(persistencePlan.normalizedChanges)));
|
|
694
|
+
const intentKeys = Object.keys(persistencePlan.normalizedChanges);
|
|
695
|
+
const persistedKeys = Object.keys(
|
|
696
|
+
persistencePlan.settingsPatch?.changes ?? {}
|
|
697
|
+
).filter((key) => key !== "schemaVersion");
|
|
698
|
+
const isCurrentIntent = () => selectIdentityUserId(getState()) === userId && getSessionGenerationForState(getState()) === session && readLocalIntentEpoch(getState) === intentEpoch;
|
|
699
|
+
const performWrite = async () => {
|
|
700
|
+
if (!isCurrentIntent()) {
|
|
701
|
+
throw new SettingsWriteSupersededError();
|
|
702
|
+
}
|
|
703
|
+
const nextDefaultAgentId = normalizeDefaultAgentIdSetting(
|
|
704
|
+
persistencePlan.normalizedChanges.defaultAgentId
|
|
705
|
+
) ?? null;
|
|
706
|
+
if (hasOwn(changes, "defaultAgentId") && previousDefaultAgentId !== (nextDefaultAgentId ?? SYSTEM_DEFAULT_AGENT_ID)) {
|
|
707
|
+
await persistDefaultAgentRegister(
|
|
708
|
+
dispatch,
|
|
709
|
+
getState,
|
|
710
|
+
userId,
|
|
711
|
+
nextDefaultAgentId
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
if (persistencePlan.settingsPatch) {
|
|
715
|
+
await dispatch(
|
|
716
|
+
getSettingDbActionThunks().upsert({
|
|
717
|
+
dbKey: persistencePlan.settingsPatch.dbKey,
|
|
718
|
+
data: persistencePlan.settingsPatch.changes
|
|
719
|
+
})
|
|
720
|
+
).unwrap();
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
const settleSettingsWriteFailureAfterSuccess = () => {
|
|
724
|
+
if (!isCurrentIntent()) return;
|
|
725
|
+
const existing = getState()?.settings?.lastWriteFailure;
|
|
726
|
+
if (!existing) return;
|
|
727
|
+
const next = resolveSettingsWriteFailureAfterSuccess({
|
|
728
|
+
failure: existing,
|
|
729
|
+
accountId: userId,
|
|
730
|
+
intentKeys,
|
|
731
|
+
persistedKeys
|
|
732
|
+
});
|
|
733
|
+
if (next === existing) return;
|
|
734
|
+
dispatch(recordSettingsWriteFailure(next));
|
|
735
|
+
};
|
|
736
|
+
await enqueueAccountSettingsWrite(getState, userId, async () => {
|
|
737
|
+
let firstFailureAt = 0;
|
|
738
|
+
try {
|
|
739
|
+
await performWrite();
|
|
740
|
+
settleSettingsWriteFailureAfterSuccess();
|
|
741
|
+
return;
|
|
742
|
+
} catch (firstError) {
|
|
743
|
+
if (isSettingsWriteSupersededError(firstError)) return;
|
|
744
|
+
firstFailureAt = Date.now();
|
|
745
|
+
if (!isCurrentIntent()) return;
|
|
746
|
+
await delaySettingsWriteRetry(SETTINGS_WRITE_RETRY_BACKOFF_MS);
|
|
747
|
+
if (!isCurrentIntent()) return;
|
|
748
|
+
try {
|
|
749
|
+
await performWrite();
|
|
750
|
+
settleSettingsWriteFailureAfterSuccess();
|
|
751
|
+
return;
|
|
752
|
+
} catch (retryError) {
|
|
753
|
+
if (isSettingsWriteSupersededError(retryError)) return;
|
|
754
|
+
if (!isCurrentIntent()) return;
|
|
755
|
+
const failure = await describeSettingsWriteFailure({
|
|
756
|
+
getState,
|
|
757
|
+
accountId: userId,
|
|
758
|
+
intentEpoch,
|
|
759
|
+
intentKeys,
|
|
760
|
+
persistedKeys,
|
|
761
|
+
at: firstFailureAt
|
|
762
|
+
});
|
|
763
|
+
if (!isCurrentIntent()) return;
|
|
764
|
+
dispatch(recordSettingsWriteFailure(failure));
|
|
765
|
+
throw retryError;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
return persistencePlan.normalizedChanges;
|
|
770
|
+
});
|
|
771
|
+
var setAccountChatDisplayPreferences = createAsyncThunk(
|
|
772
|
+
"settings/setAccountChatDisplayPreferences",
|
|
773
|
+
async (changes, { dispatch, getState }) => {
|
|
774
|
+
const userId = selectIdentityUserId(getState());
|
|
775
|
+
if (!userId) throw new Error("User not found for persisting settings.");
|
|
776
|
+
const owner = getAccountChatDisplayOwner(getState);
|
|
777
|
+
owner.setAccount(userId);
|
|
778
|
+
return dispatch(persistSettingsChanges({
|
|
779
|
+
...owner.getSnapshot(),
|
|
780
|
+
...pickAccountChatDisplayPreferences(changes)
|
|
781
|
+
})).unwrap();
|
|
782
|
+
}
|
|
783
|
+
);
|
|
784
|
+
var setSettings = createAsyncThunk(
|
|
785
|
+
"settings/setSettings",
|
|
786
|
+
async (changes, { dispatch }) => {
|
|
787
|
+
const forbidden = ["showThinking", "showScrollToTopButton", "showScrollToBottomButton"];
|
|
788
|
+
if (forbidden.some((key) => Object.prototype.hasOwnProperty.call(changes, key))) {
|
|
789
|
+
throw new Error("Chat display preferences must use setAccountChatDisplayPreferences.");
|
|
790
|
+
}
|
|
791
|
+
return dispatch(persistSettingsChanges(changes)).unwrap();
|
|
792
|
+
}
|
|
793
|
+
);
|
|
794
|
+
var setSidebarWidth = createAsyncThunk(
|
|
795
|
+
"settings/setSidebarWidth",
|
|
796
|
+
async (sidebarWidth, { dispatch }) => dispatch(setSettings({ sidebarWidth })).unwrap()
|
|
797
|
+
);
|
|
798
|
+
var toggleEnableReadCurrentSpace = createAsyncThunk(
|
|
799
|
+
"settings/toggleEnableReadCurrentSpace",
|
|
800
|
+
async (_, { dispatch, getState }) => {
|
|
801
|
+
const current = getState().settings.enableReadCurrentSpace;
|
|
802
|
+
return dispatch(
|
|
803
|
+
setSettings({
|
|
804
|
+
enableReadCurrentSpace: !current,
|
|
805
|
+
spaceContextLevel: current ? 1 : DEFAULT_USER_PREFERENCE_PROFILE.spaceContextLevel
|
|
806
|
+
})
|
|
807
|
+
).unwrap();
|
|
808
|
+
}
|
|
809
|
+
);
|
|
810
|
+
var setEditorDefaultMode = createAsyncThunk(
|
|
811
|
+
"settings/setEditorDefaultMode",
|
|
812
|
+
async (mode, { dispatch }) => dispatch(setSettings({ editorDefaultMode: mode })).unwrap()
|
|
813
|
+
);
|
|
814
|
+
var setEditorLightCodeTheme = createAsyncThunk(
|
|
815
|
+
"settings/setEditorLightCodeTheme",
|
|
816
|
+
async (theme, { dispatch }) => dispatch(setSettings({ editorLightCodeTheme: theme })).unwrap()
|
|
817
|
+
);
|
|
818
|
+
var setEditorDarkCodeTheme = createAsyncThunk(
|
|
819
|
+
"settings/setEditorDarkCodeTheme",
|
|
820
|
+
async (theme, { dispatch }) => dispatch(setSettings({ editorDarkCodeTheme: theme })).unwrap()
|
|
821
|
+
);
|
|
822
|
+
var setEditorCodeTheme = createAsyncThunk(
|
|
823
|
+
"settings/setEditorCodeTheme",
|
|
824
|
+
async (theme, { dispatch }) => dispatch(
|
|
825
|
+
setSettings({
|
|
826
|
+
editorLightCodeTheme: theme,
|
|
827
|
+
editorDarkCodeTheme: theme
|
|
828
|
+
})
|
|
829
|
+
).unwrap()
|
|
830
|
+
);
|
|
831
|
+
var toggleEditorWordCount = createAsyncThunk(
|
|
832
|
+
"settings/toggleEditorWordCount",
|
|
833
|
+
async (_, { dispatch, getState }) => {
|
|
834
|
+
const current = getState().settings.editorWordCountEnabled;
|
|
835
|
+
return dispatch(setSettings({ editorWordCountEnabled: !current })).unwrap();
|
|
836
|
+
}
|
|
837
|
+
);
|
|
838
|
+
var toggleEditorShortcut = createAsyncThunk(
|
|
839
|
+
"settings/toggleEditorShortcut",
|
|
840
|
+
async (key, { dispatch, getState }) => {
|
|
841
|
+
const currentShortcuts = getState().settings.editorShortcuts;
|
|
842
|
+
const newShortcuts = {
|
|
843
|
+
...currentShortcuts,
|
|
844
|
+
[key]: !currentShortcuts[key]
|
|
845
|
+
};
|
|
846
|
+
return dispatch(setSettings({ editorShortcuts: newShortcuts })).unwrap();
|
|
847
|
+
}
|
|
848
|
+
);
|
|
849
|
+
var setEditorFontSize = createAsyncThunk(
|
|
850
|
+
"settings/setEditorFontSize",
|
|
851
|
+
async (fontSize, { dispatch }) => dispatch(setSettings({ editorFontSize: fontSize })).unwrap()
|
|
852
|
+
);
|
|
853
|
+
var toggleEditorAutoSave = createAsyncThunk(
|
|
854
|
+
"settings/toggleEditorAutoSave",
|
|
855
|
+
async (_, { dispatch, getState }) => {
|
|
856
|
+
const current = getState().settings.editorAutoSave;
|
|
857
|
+
return dispatch(setSettings({ editorAutoSave: !current })).unwrap();
|
|
858
|
+
}
|
|
859
|
+
);
|
|
860
|
+
var setEditorAutoSaveInterval = createAsyncThunk(
|
|
861
|
+
"settings/setEditorAutoSaveInterval",
|
|
862
|
+
async (interval, { dispatch }) => dispatch(setSettings({ editorAutoSaveInterval: interval })).unwrap()
|
|
863
|
+
);
|
|
864
|
+
var setGlobalPrompt = createAsyncThunk(
|
|
865
|
+
"settings/setGlobalPrompt",
|
|
866
|
+
async (prompt, { dispatch }) => dispatch(setSettings({ globalPrompt: prompt })).unwrap()
|
|
867
|
+
);
|
|
868
|
+
var setUserTonePreset = createAsyncThunk(
|
|
869
|
+
"settings/setUserTonePreset",
|
|
870
|
+
async (tone, { dispatch }) => dispatch(setSettings({ userTonePreset: tone })).unwrap()
|
|
871
|
+
);
|
|
872
|
+
var setKnowledgeCaptureLevel = createAsyncThunk(
|
|
873
|
+
"settings/setKnowledgeCaptureLevel",
|
|
874
|
+
async (level, { dispatch }) => dispatch(setSettings({ knowledgeCaptureLevel: level })).unwrap()
|
|
875
|
+
);
|
|
876
|
+
var setSpaceContextLevel = createAsyncThunk(
|
|
877
|
+
"settings/setSpaceContextLevel",
|
|
878
|
+
async (level, { dispatch }) => dispatch(
|
|
879
|
+
setSettings({
|
|
880
|
+
spaceContextLevel: level,
|
|
881
|
+
enableReadCurrentSpace: level > 1
|
|
882
|
+
})
|
|
883
|
+
).unwrap()
|
|
884
|
+
);
|
|
885
|
+
var setAiRecentContentLimit = createAsyncThunk(
|
|
886
|
+
"settings/setAiRecentContentLimit",
|
|
887
|
+
async (limit, { dispatch }) => dispatch(setSettings({ aiRecentContentLimit: limit })).unwrap()
|
|
888
|
+
);
|
|
889
|
+
var setMaxExecutionTime = createAsyncThunk(
|
|
890
|
+
"settings/setMaxExecutionTime",
|
|
891
|
+
async (time, { dispatch }) => dispatch(setSettings({ maxExecutionTime: time })).unwrap()
|
|
892
|
+
);
|
|
893
|
+
var setDefaultAgentId = createAsyncThunk(
|
|
894
|
+
"settings/setDefaultAgentId",
|
|
895
|
+
async (agentId, { dispatch }) => dispatch(
|
|
896
|
+
setSettings({
|
|
897
|
+
defaultAgentId: resolveDefaultAgentIdSetting(agentId)
|
|
898
|
+
})
|
|
899
|
+
).unwrap()
|
|
900
|
+
);
|
|
901
|
+
export {
|
|
902
|
+
getSettings,
|
|
903
|
+
setAccountChatDisplayPreferences,
|
|
904
|
+
setAiRecentContentLimit,
|
|
905
|
+
setDefaultAgentId,
|
|
906
|
+
setEditorAutoSaveInterval,
|
|
907
|
+
setEditorCodeTheme,
|
|
908
|
+
setEditorDarkCodeTheme,
|
|
909
|
+
setEditorDefaultMode,
|
|
910
|
+
setEditorFontSize,
|
|
911
|
+
setEditorLightCodeTheme,
|
|
912
|
+
setGlobalPrompt,
|
|
913
|
+
setKnowledgeCaptureLevel,
|
|
914
|
+
setMaxExecutionTime,
|
|
915
|
+
setSettings,
|
|
916
|
+
setSidebarWidth,
|
|
917
|
+
setSpaceContextLevel,
|
|
918
|
+
setUserTonePreset,
|
|
919
|
+
toggleEditorAutoSave,
|
|
920
|
+
toggleEditorShortcut,
|
|
921
|
+
toggleEditorWordCount,
|
|
922
|
+
toggleEnableReadCurrentSpace
|
|
923
|
+
};
|