codex-overleaf-link 2.1.5 → 2.2.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/README.md +27 -23
- package/extension/bootstrap/background.js +14 -1
- package/extension/bootstrap/manifest.template.json +1 -1
- package/extension/runtime-manifest.json +10 -0
- package/extension/src/background.js +507 -8
- package/extension/src/backgroundUpdateCoordinator.js +284 -19
- package/extension/src/content/activeTurnControl.js +179 -0
- package/extension/src/content/composerPanel.js +14 -5
- package/extension/src/content/contentRuntime.js +330 -309
- package/extension/src/content/diagnosticsPanel.js +132 -1
- package/extension/src/content/markdownDomRenderer.js +451 -0
- package/extension/src/content/markdownText.js +86 -7
- package/extension/src/content/mathText.js +49 -4
- package/extension/src/content/modelPicker.js +14 -5
- package/extension/src/content/nativeChannel.js +7 -1
- package/extension/src/content/panelRenderer.js +112 -12
- package/extension/src/content/pendingInputView.js +106 -0
- package/extension/src/content/projectProviderSelection.js +68 -0
- package/extension/src/content/projectSessionCleanup.js +4 -0
- package/extension/src/content/providerSettingsCoordinator.js +170 -22
- package/extension/src/content/providerSettingsDialog.js +2 -2
- package/extension/src/content/recentProjects.js +7 -2
- package/extension/src/content/runGuidanceController.js +70 -0
- package/extension/src/content/runGuidanceView.js +48 -0
- package/extension/src/content/runQueueScheduler.js +260 -0
- package/extension/src/content/runTimelineView.js +33 -80
- package/extension/src/content/sessionManager.js +2 -2
- package/extension/src/content/sessionPersistence.js +62 -0
- package/extension/src/content/settingsPanel.js +1 -1
- package/extension/src/content/updateNotice.js +80 -1
- package/extension/src/page/writebackRouter.js +3 -9
- package/extension/src/shared/compatibility.js +2 -1
- package/extension/src/shared/i18n.js +38 -0
- package/extension/src/shared/providerProfiles.js +3 -2
- package/extension/src/shared/runInputQueue.js +253 -0
- package/extension/src/shared/sessionState.js +45 -22
- package/extension/src/shared/storageDb.js +39 -44
- package/extension/src/shared/storageMigration.js +123 -3
- package/extension/src/shared/storageRunActions.js +34 -1
- package/extension/src/shared/updateConsent.js +15 -4
- package/extension/styles/panel.css +319 -20
- package/extension/vendor/katex/katex.min.css +1 -1
- package/extension/vendor/markdown-it/LICENSE +22 -0
- package/extension/vendor/markdown-it/SOURCE.json +7 -0
- package/extension/vendor/markdown-it/VERSION +1 -0
- package/extension/vendor/markdown-it/markdown-it.min.js +3 -0
- package/native-host/src/anthropicBridgeRequest.js +3 -3
- package/native-host/src/anthropicBridgeResponse.js +58 -17
- package/native-host/src/anthropicMessagesBridge.js +156 -23
- package/native-host/src/chatBridgeRequest.js +1 -1
- package/native-host/src/chatBridgeResponse.js +12 -8
- package/native-host/src/chatCompletionsBridge.js +22 -40
- package/native-host/src/codexPromptAssembly.js +3 -1
- package/native-host/src/codexProviderLaunch.js +6 -3
- package/native-host/src/codexSessionRunner.js +65 -65
- package/native-host/src/codexSessionTiming.js +45 -0
- package/native-host/src/index.js +58 -3
- package/native-host/src/managedInstall.js +45 -7
- package/native-host/src/providerProfile.js +2 -2
- package/native-host/src/providerStreamLifecycle.js +100 -0
- package/native-host/src/responsesPassthroughBridge.js +636 -0
- package/native-host/src/taskRunnerRuntime.js +81 -2
- package/native-host/src/updateArchive.js +4 -3
- package/native-host/src/updateManager.js +306 -19
- package/native-host/src/updateTrust.js +1 -1
- package/package.json +3 -1
|
@@ -528,15 +528,9 @@
|
|
|
528
528
|
}
|
|
529
529
|
const CANCELLED_RACE_SENTINEL = Symbol('writebackRouter.cancelled');
|
|
530
530
|
async function raceOpAgainstCancellation(opPromise) {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
opPromise,
|
|
535
|
-
racer.promise.then(() => CANCELLED_RACE_SENTINEL)
|
|
536
|
-
]);
|
|
537
|
-
} finally {
|
|
538
|
-
racer.dispose();
|
|
539
|
-
}
|
|
531
|
+
// Once an editor operation starts, preserve its actual result and undo
|
|
532
|
+
// metadata. The loop's pre-operation cancellation check stops the tail.
|
|
533
|
+
return await opPromise;
|
|
540
534
|
}
|
|
541
535
|
|
|
542
536
|
for (const rawOperation of operations) {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
const MIN_NATIVE_VERSION = '1.0.0';
|
|
13
13
|
const MIN_COMPATIBLE_NATIVE_VERSION = '1.0.0';
|
|
14
14
|
const MIN_COMPATIBLE_EXTENSION_VERSION = '1.0.0';
|
|
15
|
-
const BUILD_TARGET_VERSION = '2.
|
|
15
|
+
const BUILD_TARGET_VERSION = '2.2.0';
|
|
16
16
|
const DEFAULT_CHROME_EXTENSION_ID = 'illdpneeeopfffmiepaejglgmhpmdhdc';
|
|
17
17
|
const REQUIRED_CAPABILITIES = Object.freeze([
|
|
18
18
|
'bridgePing',
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
'mirrorStatus',
|
|
22
22
|
'codexRun',
|
|
23
23
|
'codexCancel',
|
|
24
|
+
'codexSteer',
|
|
24
25
|
'codexModels',
|
|
25
26
|
'historyClearPlugin',
|
|
26
27
|
'localSkills',
|
|
@@ -292,6 +292,7 @@
|
|
|
292
292
|
providerSettingsHelp: 'Configure experimental third-party model APIs. Compatibility varies by provider and gateway.',
|
|
293
293
|
providerSettingsConfigure: 'Configure',
|
|
294
294
|
providerSettingsBuiltin: 'Built-in Codex is active',
|
|
295
|
+
providerSettingsLoading: 'Checking current project provider…',
|
|
295
296
|
storageUsageLoading: 'Calculating usage\u2026',
|
|
296
297
|
storageClearAll: 'Clear all history\u2026',
|
|
297
298
|
storageClearAllHelp: 'Removes every stored session, run and audit record for all projects. Project settings and rules are kept.',
|
|
@@ -344,6 +345,24 @@
|
|
|
344
345
|
warmMirrorStaleBlockedTitle: 'Blocked: local workspace is stale',
|
|
345
346
|
send: 'Send',
|
|
346
347
|
cancelRun: 'Cancel Current Task',
|
|
348
|
+
queueNextInput: 'Queue follow-up',
|
|
349
|
+
queuedInputQueued: 'Queued',
|
|
350
|
+
queuedInputPaused: 'Queue paused',
|
|
351
|
+
queuedInputGuiding: 'Sending guidance',
|
|
352
|
+
queuedInputExecuting: 'Running',
|
|
353
|
+
queuedInputGuide: 'Guide',
|
|
354
|
+
queuedInputGuideTitle: 'Send this message into the active Codex turn now.',
|
|
355
|
+
queuedInputGuideUnavailable: 'The active turn is not ready for guidance yet.',
|
|
356
|
+
queuedInputGuideFailed: 'Guidance could not be delivered. The message remains queued.',
|
|
357
|
+
queuedInputGuided: 'Follow-up guidance was delivered to the active Codex turn.',
|
|
358
|
+
queuedInputAdded: 'Follow-up queued. It will run after this task settles.',
|
|
359
|
+
queuedInputResume: 'Resume',
|
|
360
|
+
queuedInputRemove: 'Remove',
|
|
361
|
+
queuedInputAttachmentsUnsupported: 'Queued follow-ups currently support text and @context. Remove binary attachments before queuing.',
|
|
362
|
+
queuedInputError_empty_input: 'Enter a follow-up first.',
|
|
363
|
+
queuedInputError_input_too_long: 'This follow-up is too long to queue.',
|
|
364
|
+
queuedInputError_queue_full: 'The follow-up queue is full.',
|
|
365
|
+
queuedInputError_queue_too_large: 'The follow-up queue reached its storage limit.',
|
|
347
366
|
contextTitle: '@ Context',
|
|
348
367
|
refreshFileList: 'Refresh file list',
|
|
349
368
|
contextStatus: 'Type @ to add files, or click +: files, attachments (PDF/images), @compile-log.',
|
|
@@ -786,6 +805,7 @@
|
|
|
786
805
|
providerSettingsHelp: '配置实验性第三方模型 API;兼容性取决于具体模型服务与网关。',
|
|
787
806
|
providerSettingsConfigure: '配置',
|
|
788
807
|
providerSettingsBuiltin: '当前使用内置 Codex',
|
|
808
|
+
providerSettingsLoading: '正在读取当前项目的模型服务…',
|
|
789
809
|
storageUsageLoading: '正在计算占用…',
|
|
790
810
|
storageClearAll: '清空全部历史…',
|
|
791
811
|
storageClearAllHelp: '删除所有项目已存储的全部会话、运行与审计记录。项目设置与规则会保留。',
|
|
@@ -838,6 +858,24 @@
|
|
|
838
858
|
warmMirrorStaleBlockedTitle: '已阻止:本地 workspace 过期',
|
|
839
859
|
send: '发送',
|
|
840
860
|
cancelRun: '中断当前任务',
|
|
861
|
+
queueNextInput: '加入后续队列',
|
|
862
|
+
queuedInputQueued: '已排队',
|
|
863
|
+
queuedInputPaused: '队列已暂停',
|
|
864
|
+
queuedInputGuiding: '正在发送引导',
|
|
865
|
+
queuedInputExecuting: '正在运行',
|
|
866
|
+
queuedInputGuide: '立即引导',
|
|
867
|
+
queuedInputGuideTitle: '立即把这条消息发送到当前 Codex turn。',
|
|
868
|
+
queuedInputGuideUnavailable: '当前 turn 尚未进入可引导状态。',
|
|
869
|
+
queuedInputGuideFailed: '引导消息未送达,消息已保留在队列中。',
|
|
870
|
+
queuedInputGuided: '后续引导已发送到当前 Codex turn。',
|
|
871
|
+
queuedInputAdded: '后续任务已排队,将在当前任务完整结束后执行。',
|
|
872
|
+
queuedInputResume: '恢复队列',
|
|
873
|
+
queuedInputRemove: '删除',
|
|
874
|
+
queuedInputAttachmentsUnsupported: '当前排队消息支持文本和 @context;请先移除二进制附件。',
|
|
875
|
+
queuedInputError_empty_input: '请先输入后续任务。',
|
|
876
|
+
queuedInputError_input_too_long: '这条后续任务太长,无法排队。',
|
|
877
|
+
queuedInputError_queue_full: '后续任务队列已满。',
|
|
878
|
+
queuedInputError_queue_too_large: '后续任务队列已达到存储上限。',
|
|
841
879
|
contextTitle: '@ 上下文',
|
|
842
880
|
refreshFileList: '刷新文件列表',
|
|
843
881
|
contextStatus: '输入 @ 添加文件,或点 +:文件、附件(PDF/图片)、@compile-log。',
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
anthropicThinkingMode: 'budget',
|
|
160
160
|
anthropicPromptCaching: false,
|
|
161
161
|
impersonateClaudeCode: false,
|
|
162
|
-
maxOutputTokens:
|
|
162
|
+
maxOutputTokens: 65536,
|
|
163
163
|
hasSecret: false,
|
|
164
164
|
secretUpdatedAt: 0,
|
|
165
165
|
endpointDisclosureHost: '',
|
|
@@ -280,7 +280,8 @@
|
|
|
280
280
|
|
|
281
281
|
function normalizeMaxOutputTokens(value) {
|
|
282
282
|
const number = normalizeInteger(value);
|
|
283
|
-
|
|
283
|
+
if (!number || number === 8192 || number === 32768) return 65536;
|
|
284
|
+
return Math.min(65536, Math.max(256, number));
|
|
284
285
|
}
|
|
285
286
|
|
|
286
287
|
return {
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
(function initCodexOverleafRunInputQueue(root, factory) {
|
|
2
|
+
if (typeof module === 'object' && module.exports) {
|
|
3
|
+
module.exports = factory();
|
|
4
|
+
} else {
|
|
5
|
+
root.CodexOverleafRunInputQueue = factory();
|
|
6
|
+
}
|
|
7
|
+
})(typeof window !== 'undefined' ? window : globalThis, function runInputQueueFactory() {
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
const MAX_ITEMS = 20;
|
|
11
|
+
const MAX_TEXT_CHARS = 12000;
|
|
12
|
+
const MAX_QUEUE_BYTES = 128 * 1024;
|
|
13
|
+
const ACTIVE_STATUSES = new Set(['claimed', 'executing', 'steering']);
|
|
14
|
+
const VALID_STATUSES = new Set(['queued', 'paused', ...ACTIVE_STATUSES]);
|
|
15
|
+
|
|
16
|
+
function normalizeQueue(items, options = {}) {
|
|
17
|
+
const seen = new Set();
|
|
18
|
+
const normalized = [];
|
|
19
|
+
for (const raw of Array.isArray(items) ? items : []) {
|
|
20
|
+
const text = String(raw?.text || '').trim().slice(0, MAX_TEXT_CHARS);
|
|
21
|
+
const id = String(raw?.id || '').trim();
|
|
22
|
+
if (!id || !text || seen.has(id)) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
seen.add(id);
|
|
26
|
+
let status = VALID_STATUSES.has(raw.status) ? raw.status : 'queued';
|
|
27
|
+
if (options.recoverActive === true && ACTIVE_STATUSES.has(status)) {
|
|
28
|
+
status = 'paused';
|
|
29
|
+
}
|
|
30
|
+
normalized.push({
|
|
31
|
+
id,
|
|
32
|
+
clientUserMessageId: String(raw.clientUserMessageId || id),
|
|
33
|
+
text,
|
|
34
|
+
status,
|
|
35
|
+
createdAt: normalizeTimestamp(raw.createdAt),
|
|
36
|
+
updatedAt: normalizeTimestamp(raw.updatedAt),
|
|
37
|
+
sourceRunId: String(raw.sourceRunId || ''),
|
|
38
|
+
linkedRunId: status === 'executing' ? String(raw.linkedRunId || '') : '',
|
|
39
|
+
claimToken: status === 'claimed' || status === 'executing' ? String(raw.claimToken || '') : '',
|
|
40
|
+
pauseReason: status === 'paused' ? String(raw.pauseReason || '') : '',
|
|
41
|
+
payload: normalizePayload(raw.payload)
|
|
42
|
+
});
|
|
43
|
+
if (normalized.length >= MAX_ITEMS) {
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return trimToBudget(normalized);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function enqueue(items, input = {}, deps = {}) {
|
|
51
|
+
const queue = normalizeQueue(items);
|
|
52
|
+
const text = String(input.text || '').trim();
|
|
53
|
+
if (!text) {
|
|
54
|
+
return failure(queue, 'empty_input');
|
|
55
|
+
}
|
|
56
|
+
if (text.length > MAX_TEXT_CHARS) {
|
|
57
|
+
return failure(queue, 'input_too_long');
|
|
58
|
+
}
|
|
59
|
+
if (queue.length >= MAX_ITEMS) {
|
|
60
|
+
return failure(queue, 'queue_full');
|
|
61
|
+
}
|
|
62
|
+
const idFactory = deps.randomUUID || (() => 'pending_' + Date.now().toString(36) + '_' + Math.random().toString(36).slice(2, 8));
|
|
63
|
+
const nowFactory = deps.now || (() => new Date().toISOString());
|
|
64
|
+
const id = String(input.id || idFactory());
|
|
65
|
+
const timestamp = String(nowFactory());
|
|
66
|
+
const item = {
|
|
67
|
+
id,
|
|
68
|
+
clientUserMessageId: String(input.clientUserMessageId || id),
|
|
69
|
+
text,
|
|
70
|
+
status: input.status === 'paused' ? 'paused' : 'queued',
|
|
71
|
+
createdAt: timestamp,
|
|
72
|
+
updatedAt: timestamp,
|
|
73
|
+
sourceRunId: String(input.sourceRunId || ''),
|
|
74
|
+
linkedRunId: '',
|
|
75
|
+
claimToken: '',
|
|
76
|
+
pauseReason: input.status === 'paused' ? String(input.pauseReason || '') : '',
|
|
77
|
+
payload: normalizePayload(input.payload)
|
|
78
|
+
};
|
|
79
|
+
const next = [...queue, item];
|
|
80
|
+
if (estimateBytes(next) > MAX_QUEUE_BYTES) {
|
|
81
|
+
return failure(queue, 'queue_too_large');
|
|
82
|
+
}
|
|
83
|
+
return { ok: true, queue: next, item };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function remove(items, id) {
|
|
87
|
+
return normalizeQueue(items).filter(item => item.id !== id);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function markSteering(items, id) {
|
|
91
|
+
return update(items, id, item => ({
|
|
92
|
+
...item,
|
|
93
|
+
status: 'steering',
|
|
94
|
+
updatedAt: new Date().toISOString(),
|
|
95
|
+
pauseReason: ''
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function returnToQueue(items, id, reason = '') {
|
|
100
|
+
return update(items, id, item => ({
|
|
101
|
+
...item,
|
|
102
|
+
status: 'queued',
|
|
103
|
+
updatedAt: new Date().toISOString(),
|
|
104
|
+
linkedRunId: '',
|
|
105
|
+
claimToken: '',
|
|
106
|
+
pauseReason: String(reason || '')
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function claimNext(items, deps = {}) {
|
|
111
|
+
const queue = normalizeQueue(items);
|
|
112
|
+
const index = queue.findIndex(item => item.status === 'queued');
|
|
113
|
+
if (index < 0) {
|
|
114
|
+
return { ok: false, queue, item: null };
|
|
115
|
+
}
|
|
116
|
+
const tokenFactory = deps.randomUUID || (() => 'claim_' + Date.now().toString(36) + '_' + Math.random().toString(36).slice(2, 8));
|
|
117
|
+
const item = {
|
|
118
|
+
...queue[index],
|
|
119
|
+
status: 'claimed',
|
|
120
|
+
claimToken: String(tokenFactory()),
|
|
121
|
+
updatedAt: new Date().toISOString(),
|
|
122
|
+
pauseReason: ''
|
|
123
|
+
};
|
|
124
|
+
queue[index] = item;
|
|
125
|
+
return { ok: true, queue, item };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function markExecuting(items, id, linkedRunId) {
|
|
129
|
+
return update(items, id, item => ({
|
|
130
|
+
...item,
|
|
131
|
+
status: 'executing',
|
|
132
|
+
linkedRunId: String(linkedRunId || ''),
|
|
133
|
+
updatedAt: new Date().toISOString()
|
|
134
|
+
}));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function pauseAll(items, reason = '') {
|
|
138
|
+
return normalizeQueue(items).map(item => ({
|
|
139
|
+
...item,
|
|
140
|
+
status: 'paused',
|
|
141
|
+
linkedRunId: '',
|
|
142
|
+
claimToken: '',
|
|
143
|
+
pauseReason: String(reason || ''),
|
|
144
|
+
updatedAt: new Date().toISOString()
|
|
145
|
+
}));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function resumeAll(items) {
|
|
149
|
+
return normalizeQueue(items).map(item => ({
|
|
150
|
+
...item,
|
|
151
|
+
status: 'queued',
|
|
152
|
+
linkedRunId: '',
|
|
153
|
+
claimToken: '',
|
|
154
|
+
pauseReason: '',
|
|
155
|
+
updatedAt: new Date().toISOString()
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function update(items, id, updater) {
|
|
160
|
+
return normalizeQueue(items).map(item => item.id === id ? updater(item) : item);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function normalizePayload(payload = {}) {
|
|
164
|
+
return {
|
|
165
|
+
mode: ['ask', 'confirm', 'auto'].includes(payload.mode) ? payload.mode : 'ask',
|
|
166
|
+
providerId: String(payload.providerId || 'builtin').slice(0, 160),
|
|
167
|
+
providerRevision: String(payload.providerRevision || '').slice(0, 160),
|
|
168
|
+
model: String(payload.model || '').slice(0, 160),
|
|
169
|
+
reasoningEffort: String(payload.reasoningEffort || '').slice(0, 32),
|
|
170
|
+
speedTier: payload.speedTier === 'fast' ? 'fast' : 'standard',
|
|
171
|
+
autoRecompile: payload.autoRecompile !== false,
|
|
172
|
+
requireReviewing: payload.requireReviewing !== false,
|
|
173
|
+
focusFiles: (Array.isArray(payload.focusFiles) ? payload.focusFiles : [])
|
|
174
|
+
.map(path => String(path || '').replace(/\\/g, '/').replace(/^\/+/, '').trim())
|
|
175
|
+
.filter(Boolean)
|
|
176
|
+
.slice(0, 100)
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function normalizeTimestamp(value) {
|
|
181
|
+
return typeof value === 'string' && value ? value : new Date().toISOString();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
function trimToBudget(items) {
|
|
185
|
+
const queue = items.slice(-MAX_ITEMS);
|
|
186
|
+
while (queue.length && estimateBytes(queue) > MAX_QUEUE_BYTES) {
|
|
187
|
+
queue.shift();
|
|
188
|
+
}
|
|
189
|
+
return queue;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function estimateBytes(value) {
|
|
193
|
+
const text = JSON.stringify(value);
|
|
194
|
+
return typeof TextEncoder !== 'undefined'
|
|
195
|
+
? new TextEncoder().encode(text).length
|
|
196
|
+
: text.length * 2;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function compactForStorage(items, helpers = {}) {
|
|
200
|
+
const normalizeField = helpers.normalizeField || (value => String(value || ''));
|
|
201
|
+
const normalizeDisplay = helpers.normalizeDisplay || normalizeField;
|
|
202
|
+
const normalizePaths = helpers.normalizePaths || (value => normalizePayload({ focusFiles: value }).focusFiles);
|
|
203
|
+
return (Array.isArray(items) ? items : [])
|
|
204
|
+
.slice(-MAX_ITEMS)
|
|
205
|
+
.map(item => {
|
|
206
|
+
const payload = item?.payload && typeof item.payload === 'object' ? item.payload : {};
|
|
207
|
+
return {
|
|
208
|
+
id: normalizeField(item?.id, 160),
|
|
209
|
+
clientUserMessageId: normalizeField(item?.clientUserMessageId, 160),
|
|
210
|
+
text: normalizeDisplay(item?.text, MAX_TEXT_CHARS),
|
|
211
|
+
status: VALID_STATUSES.has(item?.status) ? item.status : 'queued',
|
|
212
|
+
createdAt: typeof item?.createdAt === 'string' ? item.createdAt : '',
|
|
213
|
+
updatedAt: typeof item?.updatedAt === 'string' ? item.updatedAt : '',
|
|
214
|
+
sourceRunId: normalizeField(item?.sourceRunId, 160),
|
|
215
|
+
linkedRunId: normalizeField(item?.linkedRunId, 160),
|
|
216
|
+
claimToken: normalizeField(item?.claimToken, 160),
|
|
217
|
+
pauseReason: normalizeField(item?.pauseReason, 160),
|
|
218
|
+
payload: {
|
|
219
|
+
mode: typeof payload.mode === 'string' ? payload.mode : 'ask',
|
|
220
|
+
providerId: normalizeField(payload.providerId, 160) || 'builtin',
|
|
221
|
+
providerRevision: normalizeField(payload.providerRevision, 160),
|
|
222
|
+
model: normalizeField(payload.model, 160),
|
|
223
|
+
reasoningEffort: normalizeField(payload.reasoningEffort, 32),
|
|
224
|
+
speedTier: payload.speedTier === 'fast' ? 'fast' : 'standard',
|
|
225
|
+
autoRecompile: payload.autoRecompile !== false,
|
|
226
|
+
requireReviewing: payload.requireReviewing !== false,
|
|
227
|
+
focusFiles: normalizePaths(payload.focusFiles)
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
})
|
|
231
|
+
.filter(item => item.id && item.text);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function failure(queue, code) {
|
|
235
|
+
return { ok: false, queue, item: null, error: { code } };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
MAX_ITEMS,
|
|
240
|
+
MAX_QUEUE_BYTES,
|
|
241
|
+
MAX_TEXT_CHARS,
|
|
242
|
+
claimNext,
|
|
243
|
+
compactForStorage,
|
|
244
|
+
enqueue,
|
|
245
|
+
markExecuting,
|
|
246
|
+
markSteering,
|
|
247
|
+
normalizeQueue,
|
|
248
|
+
pauseAll,
|
|
249
|
+
remove,
|
|
250
|
+
resumeAll,
|
|
251
|
+
returnToQueue
|
|
252
|
+
};
|
|
253
|
+
});
|
|
@@ -127,6 +127,9 @@
|
|
|
127
127
|
if (!VALID_SPEED_TIERS.has(state.speedTier)) {
|
|
128
128
|
state.speedTier = DEFAULT_PANEL_STATE.speedTier;
|
|
129
129
|
}
|
|
130
|
+
state.providerId = typeof state.providerId === 'string' && state.providerId.trim()
|
|
131
|
+
? state.providerId.trim()
|
|
132
|
+
: 'builtin';
|
|
130
133
|
if (!VALID_LOCALES.has(state.locale)) {
|
|
131
134
|
state.locale = DEFAULT_PANEL_STATE.locale;
|
|
132
135
|
}
|
|
@@ -178,7 +181,7 @@
|
|
|
178
181
|
...legacySession,
|
|
179
182
|
task: state.task,
|
|
180
183
|
mode: state.mode,
|
|
181
|
-
providerId:
|
|
184
|
+
providerId: state.providerId,
|
|
182
185
|
model: state.model,
|
|
183
186
|
reasoningEffort: state.reasoningEffort,
|
|
184
187
|
speedTier: state.speedTier,
|
|
@@ -212,7 +215,7 @@
|
|
|
212
215
|
mode: VALID_MODES.has(session.mode) ? session.mode : fallbackState.mode,
|
|
213
216
|
providerId: typeof session.providerId === 'string' && session.providerId.trim()
|
|
214
217
|
? session.providerId.trim()
|
|
215
|
-
: 'builtin',
|
|
218
|
+
: (fallbackState.providerId || 'builtin'),
|
|
216
219
|
model: typeof session.model === 'string' && session.model ? session.model : fallbackState.model,
|
|
217
220
|
reasoningEffort: VALID_REASONING.has(session.reasoningEffort)
|
|
218
221
|
? session.reasoningEffort
|
|
@@ -222,7 +225,8 @@
|
|
|
222
225
|
: fallbackState.speedTier,
|
|
223
226
|
requireReviewing: session.requireReviewing !== false,
|
|
224
227
|
focusFiles: normalizeFocusFiles(session.focusFiles),
|
|
225
|
-
codexThreadId: typeof session.codexThreadId === 'string' ? session.codexThreadId : ''
|
|
228
|
+
codexThreadId: typeof session.codexThreadId === 'string' ? session.codexThreadId : '',
|
|
229
|
+
pendingInputs: normalizePendingInputs(session.pendingInputs, options.restoreRunningRuns === true)
|
|
226
230
|
};
|
|
227
231
|
}
|
|
228
232
|
|
|
@@ -291,22 +295,12 @@
|
|
|
291
295
|
history: Array.isArray(active.history) ? active.history.slice(-10) : [],
|
|
292
296
|
focusFiles: normalizeFocusFiles(active.focusFiles),
|
|
293
297
|
codexThreadId: active.codexThreadId || '',
|
|
294
|
-
providerId:
|
|
298
|
+
providerId: state.providerId || 'builtin'
|
|
295
299
|
};
|
|
296
300
|
state.runs = Array.isArray(active.runs) ? active.runs : [];
|
|
297
301
|
state.task = typeof active.task === 'string' ? active.task : '';
|
|
298
302
|
state.focusFiles = normalizeFocusFiles(active.focusFiles);
|
|
299
303
|
state.mode = VALID_MODES.has(active.mode) ? active.mode : DEFAULT_PANEL_STATE.mode;
|
|
300
|
-
state.providerId = typeof active.providerId === 'string' && active.providerId
|
|
301
|
-
? active.providerId
|
|
302
|
-
: 'builtin';
|
|
303
|
-
state.model = typeof active.model === 'string' && active.model ? active.model : DEFAULT_PANEL_STATE.model;
|
|
304
|
-
state.reasoningEffort = VALID_REASONING.has(active.reasoningEffort)
|
|
305
|
-
? active.reasoningEffort
|
|
306
|
-
: DEFAULT_PANEL_STATE.reasoningEffort;
|
|
307
|
-
state.speedTier = VALID_SPEED_TIERS.has(active.speedTier)
|
|
308
|
-
? active.speedTier
|
|
309
|
-
: DEFAULT_PANEL_STATE.speedTier;
|
|
310
304
|
state.requireReviewing = active.requireReviewing !== false;
|
|
311
305
|
|
|
312
306
|
return state;
|
|
@@ -341,7 +335,8 @@
|
|
|
341
335
|
: DEFAULT_PANEL_STATE.speedTier,
|
|
342
336
|
requireReviewing: overrides.requireReviewing !== false,
|
|
343
337
|
focusFiles: normalizeFocusFiles(overrides.focusFiles),
|
|
344
|
-
codexThreadId: typeof overrides.codexThreadId === 'string' ? overrides.codexThreadId : ''
|
|
338
|
+
codexThreadId: typeof overrides.codexThreadId === 'string' ? overrides.codexThreadId : '',
|
|
339
|
+
pendingInputs: normalizePendingInputs(overrides.pendingInputs)
|
|
345
340
|
};
|
|
346
341
|
}
|
|
347
342
|
|
|
@@ -623,7 +618,12 @@
|
|
|
623
618
|
undoBaseFiles: normalizeRunFiles(run.undoBaseFiles),
|
|
624
619
|
undoTrackedChanges: normalizeRunTrackedChanges(run.undoTrackedChanges),
|
|
625
620
|
undoExpectedFiles: normalizeRunFiles(run.undoExpectedFiles),
|
|
626
|
-
undoStatus: sanitizeAssistantVisibleText(run.undoStatus)
|
|
621
|
+
undoStatus: sanitizeAssistantVisibleText(run.undoStatus),
|
|
622
|
+
nativeRequestId: sanitizeAssistantVisibleText(run.nativeRequestId),
|
|
623
|
+
codexTurnId: sanitizeAssistantVisibleText(run.codexTurnId),
|
|
624
|
+
nativeEventSeq: Number.isFinite(Number(run.nativeEventSeq)) ? Number(run.nativeEventSeq) : 0,
|
|
625
|
+
queueItemId: sanitizeAssistantVisibleText(run.queueItemId),
|
|
626
|
+
interruptedDraft: run.interruptedDraft ? sanitizeAssistantVisibleValue(run.interruptedDraft) : undefined
|
|
627
627
|
};
|
|
628
628
|
|
|
629
629
|
applyTrackedChangeStatus(normalized, run.trackedChangeStatus);
|
|
@@ -720,6 +720,7 @@
|
|
|
720
720
|
timestamp: typeof event.timestamp === 'string' ? event.timestamp : '',
|
|
721
721
|
kind: typeof event.kind === 'string' ? event.kind : 'activity',
|
|
722
722
|
technicalDetail: sanitizeAssistantVisibleValue(event.technicalDetail),
|
|
723
|
+
guidanceId: sanitizeAssistantVisibleText(event.guidanceId),
|
|
723
724
|
streamKey: sanitizeAssistantVisibleText(event.streamKey),
|
|
724
725
|
streamRole: sanitizeAssistantVisibleText(event.streamRole)
|
|
725
726
|
};
|
|
@@ -965,11 +966,14 @@
|
|
|
965
966
|
codexOverleafSkills: compactCodexOverleafSkillsForStorage(source.codexOverleafSkills),
|
|
966
967
|
composerAttachments: normalizeComposerAttachmentsForPersistence(source.composerAttachments),
|
|
967
968
|
mode: VALID_MODES.has(active?.mode) ? active.mode : normalizeMode(source.mode),
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
969
|
+
providerId: typeof source.providerId === 'string' && source.providerId.trim()
|
|
970
|
+
? source.providerId.trim()
|
|
971
|
+
: 'builtin',
|
|
972
|
+
model: normalizeTextField(source.model || DEFAULT_PANEL_STATE.model, 80),
|
|
973
|
+
reasoningEffort: VALID_REASONING.has(source.reasoningEffort)
|
|
974
|
+
? source.reasoningEffort
|
|
971
975
|
: normalizeReasoning(source.reasoningEffort),
|
|
972
|
-
speedTier: normalizeSpeedTier(
|
|
976
|
+
speedTier: normalizeSpeedTier(source.speedTier),
|
|
973
977
|
locale: normalizeLocale(source.locale),
|
|
974
978
|
requireReviewing: active ? active.requireReviewing !== false : source.requireReviewing !== false,
|
|
975
979
|
autoOpen: source.autoOpen !== false,
|
|
@@ -1058,7 +1062,9 @@
|
|
|
1058
1062
|
reasoningEffort: normalizeReasoning(session.reasoningEffort || fallbackState.reasoningEffort),
|
|
1059
1063
|
speedTier: normalizeSpeedTier(session.speedTier || fallbackState.speedTier),
|
|
1060
1064
|
requireReviewing: session.requireReviewing !== false,
|
|
1061
|
-
focusFiles: normalizeFocusFiles(session.focusFiles)
|
|
1065
|
+
focusFiles: normalizeFocusFiles(session.focusFiles),
|
|
1066
|
+
codexThreadId: typeof session.codexThreadId === 'string' ? session.codexThreadId : '',
|
|
1067
|
+
pendingInputs: normalizePendingInputs(session.pendingInputs)
|
|
1062
1068
|
};
|
|
1063
1069
|
// Welcome-panel + write-guard: preserve the four
|
|
1064
1070
|
// Recent-projects fields through compaction so they round-trip when state
|
|
@@ -1139,8 +1145,15 @@
|
|
|
1139
1145
|
undoBaseFiles: undoPayload.undoBaseFiles,
|
|
1140
1146
|
undoTrackedChanges: undoPayload.undoTrackedChanges,
|
|
1141
1147
|
undoExpectedFiles: undoPayload.undoExpectedFiles,
|
|
1142
|
-
undoStatus: summarizeTextForStorage(run.undoStatus, 'undo status')
|
|
1148
|
+
undoStatus: summarizeTextForStorage(run.undoStatus, 'undo status'),
|
|
1149
|
+
nativeRequestId: normalizeTextField(run.nativeRequestId, 160),
|
|
1150
|
+
codexTurnId: normalizeTextField(run.codexTurnId, 160),
|
|
1151
|
+
nativeEventSeq: Number.isFinite(Number(run.nativeEventSeq)) ? Number(run.nativeEventSeq) : 0,
|
|
1152
|
+
queueItemId: normalizeTextField(run.queueItemId, 160)
|
|
1143
1153
|
};
|
|
1154
|
+
if (run.interruptedDraft) {
|
|
1155
|
+
compact.interruptedDraft = sanitizeAssistantVisibleValue(run.interruptedDraft);
|
|
1156
|
+
}
|
|
1144
1157
|
if (VALID_TRACKED_CHANGE_STATUS.has(run.trackedChangeStatus)) {
|
|
1145
1158
|
compact.trackedChangeStatus = run.trackedChangeStatus;
|
|
1146
1159
|
}
|
|
@@ -1157,6 +1170,7 @@
|
|
|
1157
1170
|
status: normalizeEventStatus(event.status),
|
|
1158
1171
|
timestamp: typeof event.timestamp === 'string' ? event.timestamp : '',
|
|
1159
1172
|
kind: typeof event.kind === 'string' ? event.kind : 'activity',
|
|
1173
|
+
guidanceId: normalizeTextField(event.guidanceId, 160),
|
|
1160
1174
|
streamKey: typeof event.streamKey === 'string' ? event.streamKey : '',
|
|
1161
1175
|
streamRole: typeof event.streamRole === 'string' ? event.streamRole : ''
|
|
1162
1176
|
};
|
|
@@ -1370,6 +1384,15 @@
|
|
|
1370
1384
|
}));
|
|
1371
1385
|
}
|
|
1372
1386
|
|
|
1387
|
+
function normalizePendingInputs(value, recoverActive = false) {
|
|
1388
|
+
const Queue = (typeof globalThis !== 'undefined' ? globalThis.CodexOverleafRunInputQueue : null)
|
|
1389
|
+
|| (typeof module === 'object' && module.exports ? require('./runInputQueue') : null);
|
|
1390
|
+
if (Queue?.normalizeQueue) {
|
|
1391
|
+
return Queue.normalizeQueue(value, { recoverActive });
|
|
1392
|
+
}
|
|
1393
|
+
return [];
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1373
1396
|
function sanitizeAssistantVisibleValue(value, depth = 0) {
|
|
1374
1397
|
if (typeof value === 'string') {
|
|
1375
1398
|
return sanitizeAssistantVisibleText(value);
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
(function initStorageDb(root, factory) {
|
|
2
2
|
if (typeof module === 'object' && module.exports) {
|
|
3
|
-
module.exports = factory(require('./storageRunActions'));
|
|
3
|
+
module.exports = factory(require('./storageRunActions'), require('./runInputQueue'));
|
|
4
4
|
} else {
|
|
5
|
-
root.CodexOverleafStorageDb = factory(root.CodexOverleafStorageRunActions);
|
|
5
|
+
root.CodexOverleafStorageDb = factory(root.CodexOverleafStorageRunActions, root.CodexOverleafRunInputQueue);
|
|
6
6
|
}
|
|
7
|
-
})(typeof globalThis !== 'undefined' ? globalThis : window, function storageDbFactory(StorageRunActions) {
|
|
7
|
+
})(typeof globalThis !== 'undefined' ? globalThis : window, function storageDbFactory(StorageRunActions, RunInputQueue) {
|
|
8
8
|
'use strict';
|
|
9
|
-
if (!StorageRunActions?.compactRunsForStorage || !StorageRunActions?.compactRunActionPayload || !StorageRunActions?.compactProviderSnapshot) {
|
|
9
|
+
if (!StorageRunActions?.compactRunsForStorage || !StorageRunActions?.compactRunActionPayload || !StorageRunActions?.compactProviderSnapshot || !StorageRunActions?.compactStructuredEventValue || !StorageRunActions?.hashString || !RunInputQueue?.compactForStorage) {
|
|
10
10
|
throw new Error('Codex Overleaf storage run-action helpers are unavailable.');
|
|
11
11
|
}
|
|
12
12
|
// IndexedDB versions are monotonic; v2.0 RC profiles have already opened v3.
|
|
@@ -272,6 +272,11 @@
|
|
|
272
272
|
codexThreadId: typeof input.codexThreadId === 'string' ? input.codexThreadId : '',
|
|
273
273
|
status: typeof input.status === 'string' && input.status ? input.status : 'active',
|
|
274
274
|
focusFiles: normalizePathList(input.focusFiles),
|
|
275
|
+
pendingInputs: RunInputQueue.compactForStorage(input.pendingInputs, {
|
|
276
|
+
normalizeField: normalizeTextField,
|
|
277
|
+
normalizeDisplay: normalizeDisplayTextForStorage,
|
|
278
|
+
normalizePaths: normalizePathList
|
|
279
|
+
}),
|
|
275
280
|
history: compactHistoryForStorage(input.history),
|
|
276
281
|
runs: compactRunsForStorage(input.runs, options),
|
|
277
282
|
task: normalizeDisplayTextForStorage(input.task, SESSION_STORAGE_LIMITS.taskChars),
|
|
@@ -663,8 +668,23 @@
|
|
|
663
668
|
undoBaseFiles: actionPayload.undoBaseFiles,
|
|
664
669
|
undoTrackedChanges: actionPayload.undoTrackedChanges,
|
|
665
670
|
undoExpectedFiles: actionPayload.undoExpectedFiles,
|
|
666
|
-
undoStatus: normalizeDisplayTextForStorage(run.undoStatus, SESSION_STORAGE_LIMITS.statusTextChars)
|
|
671
|
+
undoStatus: normalizeDisplayTextForStorage(run.undoStatus, SESSION_STORAGE_LIMITS.statusTextChars),
|
|
672
|
+
nativeRequestId: normalizeTextField(run.nativeRequestId, 160),
|
|
673
|
+
codexTurnId: normalizeTextField(run.codexTurnId, 160),
|
|
674
|
+
nativeEventSeq: Number.isFinite(Number(run.nativeEventSeq)) ? Number(run.nativeEventSeq) : 0,
|
|
675
|
+
queueItemId: normalizeTextField(run.queueItemId, 160)
|
|
667
676
|
};
|
|
677
|
+
if (run.interruptedDraft && typeof run.interruptedDraft === 'object') {
|
|
678
|
+
compact.interruptedDraft = {
|
|
679
|
+
requestId: normalizeTextField(run.interruptedDraft.requestId, 160),
|
|
680
|
+
threadId: normalizeTextField(run.interruptedDraft.threadId, 160),
|
|
681
|
+
turnId: normalizeTextField(run.interruptedDraft.turnId, 160),
|
|
682
|
+
lastEventSeq: Number.isFinite(Number(run.interruptedDraft.lastEventSeq))
|
|
683
|
+
? Number(run.interruptedDraft.lastEventSeq)
|
|
684
|
+
: 0,
|
|
685
|
+
reason: normalizeTextField(run.interruptedDraft.reason, 80)
|
|
686
|
+
};
|
|
687
|
+
}
|
|
668
688
|
if (VALID_TRACKED_CHANGE_STATUSES[run.trackedChangeStatus] === true) {
|
|
669
689
|
compact.trackedChangeStatus = run.trackedChangeStatus;
|
|
670
690
|
}
|
|
@@ -712,27 +732,11 @@
|
|
|
712
732
|
// its shape while redacting + truncating every string field. Bounded depth +
|
|
713
733
|
// breadth so a pathological value can't blow up the stored record.
|
|
714
734
|
function compactStructuredEventValueForStorage(value, depth) {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
return value;
|
|
721
|
-
}
|
|
722
|
-
if (d > 6 || typeof value !== 'object') {
|
|
723
|
-
return null;
|
|
724
|
-
}
|
|
725
|
-
if (Array.isArray(value)) {
|
|
726
|
-
return value.slice(0, 32).map(function (item) {
|
|
727
|
-
return compactStructuredEventValueForStorage(item, d + 1);
|
|
728
|
-
});
|
|
729
|
-
}
|
|
730
|
-
var out = {};
|
|
731
|
-
var keys = Object.keys(value).slice(0, 32);
|
|
732
|
-
for (var i = 0; i < keys.length; i++) {
|
|
733
|
-
out[keys[i]] = compactStructuredEventValueForStorage(value[keys[i]], d + 1);
|
|
734
|
-
}
|
|
735
|
-
return out;
|
|
735
|
+
return StorageRunActions.compactStructuredEventValue(value, {
|
|
736
|
+
normalizeString: function (text) {
|
|
737
|
+
return normalizeDisplayTextForStorage(text, SESSION_STORAGE_LIMITS.reportDetailChars);
|
|
738
|
+
}
|
|
739
|
+
}, depth);
|
|
736
740
|
}
|
|
737
741
|
|
|
738
742
|
function getEventDetailLimit(event) {
|
|
@@ -1142,7 +1146,11 @@
|
|
|
1142
1146
|
return Promise.resolve([]);
|
|
1143
1147
|
}
|
|
1144
1148
|
return getAllSessions().then(function (all) {
|
|
1145
|
-
return filterRecentProjectsAcrossAccount(all, {
|
|
1149
|
+
return filterRecentProjectsAcrossAccount(all, {
|
|
1150
|
+
accountScopeId: accountScopeId,
|
|
1151
|
+
limit: limit,
|
|
1152
|
+
deletedSessionIdsByProject: options && options.deletedSessionIdsByProject
|
|
1153
|
+
});
|
|
1146
1154
|
});
|
|
1147
1155
|
}
|
|
1148
1156
|
|
|
@@ -1153,6 +1161,7 @@
|
|
|
1153
1161
|
function filterRecentProjectsAcrossAccount(sessions, options) {
|
|
1154
1162
|
var accountScopeId = options && options.accountScopeId;
|
|
1155
1163
|
var limit = options && Number.isFinite(options.limit) ? options.limit : 10;
|
|
1164
|
+
var deletedSessionIdsByProject = options && options.deletedSessionIdsByProject;
|
|
1156
1165
|
if (!accountScopeId) {
|
|
1157
1166
|
return [];
|
|
1158
1167
|
}
|
|
@@ -1163,6 +1172,8 @@
|
|
|
1163
1172
|
var s = all[i];
|
|
1164
1173
|
if (!s) continue;
|
|
1165
1174
|
if (s.accountScopeId !== accountScopeId) continue;
|
|
1175
|
+
if (deletedSessionIdsByProject && Array.isArray(deletedSessionIdsByProject[s.projectId])
|
|
1176
|
+
&& deletedSessionIdsByProject[s.projectId].indexOf(s.id) !== -1) continue;
|
|
1166
1177
|
if (typeof s.lastActivityAt !== 'string' || !s.lastActivityAt) continue;
|
|
1167
1178
|
if (!isValidOverleafProjectId(s.projectId)) continue;
|
|
1168
1179
|
var prev = byProject[s.projectId];
|
|
@@ -1303,23 +1314,7 @@
|
|
|
1303
1314
|
}
|
|
1304
1315
|
}
|
|
1305
1316
|
|
|
1306
|
-
|
|
1307
|
-
var hash = 2166136261;
|
|
1308
|
-
var text = String(value || '');
|
|
1309
|
-
for (var i = 0; i < text.length; i++) {
|
|
1310
|
-
hash ^= text.charCodeAt(i);
|
|
1311
|
-
hash = Math.imul(hash, 16777619);
|
|
1312
|
-
}
|
|
1313
|
-
return (hash >>> 0).toString(16).padStart(8, '0');
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
|
-
function cloneJsonValue(value) {
|
|
1317
|
-
try {
|
|
1318
|
-
return JSON.parse(JSON.stringify(value));
|
|
1319
|
-
} catch (_error) {
|
|
1320
|
-
return Array.isArray(value) ? value.slice() : value;
|
|
1321
|
-
}
|
|
1322
|
-
}
|
|
1317
|
+
var hashString = StorageRunActions.hashString;
|
|
1323
1318
|
|
|
1324
1319
|
return {
|
|
1325
1320
|
TARGET_SCHEMA_VERSION: TARGET_SCHEMA_VERSION,
|