codex-weixin 0.2.4 → 0.2.7

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.en.md +5 -1
  3. package/README.md +7 -1
  4. package/dist/bridge/service.d.ts +1 -0
  5. package/dist/bridge/service.js +44 -4
  6. package/dist/bridge/service.js.map +1 -1
  7. package/dist/codex/app-server-runner.d.ts +8 -0
  8. package/dist/codex/app-server-runner.js +91 -5
  9. package/dist/codex/app-server-runner.js.map +1 -1
  10. package/dist/codex/exec-runner.d.ts +2 -0
  11. package/dist/codex/exec-runner.js.map +1 -1
  12. package/dist/codex/runner.js +7 -2
  13. package/dist/codex/runner.js.map +1 -1
  14. package/dist/server/account-manager.d.ts +2 -1
  15. package/dist/server/account-manager.js +9 -2
  16. package/dist/server/account-manager.js.map +1 -1
  17. package/dist/server/http-server.d.ts +3 -0
  18. package/dist/server/http-server.js +81 -6
  19. package/dist/server/http-server.js.map +1 -1
  20. package/dist/server/index.js +40 -14
  21. package/dist/server/index.js.map +1 -1
  22. package/dist/server/restart-helper.d.ts +1 -0
  23. package/dist/server/restart-helper.js +46 -0
  24. package/dist/server/restart-helper.js.map +1 -0
  25. package/dist/server/restart.d.ts +7 -0
  26. package/dist/server/restart.js +36 -0
  27. package/dist/server/restart.js.map +1 -0
  28. package/dist/server/update-manager.d.ts +51 -0
  29. package/dist/server/update-manager.js +230 -0
  30. package/dist/server/update-manager.js.map +1 -0
  31. package/dist/state/config.d.ts +1 -0
  32. package/dist/state/config.js +2 -0
  33. package/dist/state/config.js.map +1 -1
  34. package/dist/state/runtime-state.d.ts +3 -0
  35. package/dist/state/runtime-state.js +20 -0
  36. package/dist/state/runtime-state.js.map +1 -1
  37. package/dist/web/app.js +299 -10
  38. package/dist/web/index.html +53 -4
  39. package/dist/web/styles.css +43 -2
  40. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/state/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,qBAAqB,EAAyB,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAiB9D,MAAM,UAAU,aAAa,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC;IAC1E,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;QAC7B,gBAAgB,EAAE,EAAE;QACpB,iBAAiB,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,QAAQ,EAAE,OAAO;QACjB,YAAY,EAAE,MAAM;QACpB,cAAc,EAAE,EAAE;QAClB,iBAAiB,EAAE,EAAE,GAAG,MAAM;QAC9B,eAAe,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;KAClC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAiB,EAAE,GAAY;IACxD,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACxD,MAAM,MAAM,GAAG,YAAY,CAA6B,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC9E,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACxE,OAAO;QACL,GAAG,IAAI;QACP,GAAG,MAAM;QACT,gBAAgB;QAChB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,IAAI,IAAI,CAAC,gBAAgB;QAClE,iBAAiB,EAAE,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC;aACtG,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;KAC/C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAiB,EAAE,MAAyB;IACrE,aAAa,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,iBAA2B;IAC/E,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzC,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC/C,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/state/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,qBAAqB,EAAyB,MAAM,qBAAqB,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAkB9D,MAAM,UAAU,aAAa,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC;IAC1E,OAAO;QACL,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;QAC7B,gBAAgB,EAAE,EAAE;QACpB,iBAAiB,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACtC,QAAQ,EAAE,OAAO;QACjB,YAAY,EAAE,MAAM;QACpB,aAAa,EAAE,IAAI;QACnB,cAAc,EAAE,EAAE;QAClB,iBAAiB,EAAE,EAAE,GAAG,MAAM;QAC9B,eAAe,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI;KAClC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAiB,EAAE,GAAY;IACxD,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IACxD,MAAM,MAAM,GAAG,YAAY,CAA6B,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC9E,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACxE,OAAO;QACL,GAAG,IAAI;QACP,GAAG,MAAM;QACT,gBAAgB;QAChB,aAAa,EAAE,OAAO,MAAM,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa;QACpG,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,IAAI,IAAI,CAAC,gBAAgB;QAClE,iBAAiB,EAAE,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC;aACtG,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;KAC/C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAiB,EAAE,MAAyB;IACrE,aAAa,CAAC,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,SAAiB,EAAE,iBAA2B;IAC/E,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACzC,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;QACxC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC/C,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -7,12 +7,14 @@ export type ManagedSession = {
7
7
  threadId?: string;
8
8
  model?: string;
9
9
  effort?: string;
10
+ streamReplies?: boolean;
10
11
  createdAt: string;
11
12
  updatedAt: string;
12
13
  };
13
14
  export type SessionRuntimeOverrides = {
14
15
  model?: string | null;
15
16
  effort?: string | null;
17
+ streamReplies?: boolean | null;
16
18
  };
17
19
  export type RuntimeState = {
18
20
  pairedSenderIds: string[];
@@ -50,6 +52,7 @@ export declare class RuntimeStateStore {
50
52
  getThread(senderId: string): string | undefined;
51
53
  setModelOverride(senderId: string, model?: string): void;
52
54
  setEffortOverride(senderId: string, effort?: string): void;
55
+ setStreamRepliesOverride(senderId: string, streamReplies?: boolean): void;
53
56
  listSessions(): ManagedSession[];
54
57
  getSession(sessionId: string): ManagedSession | undefined;
55
58
  getActiveSession(senderId: string): ManagedSession | undefined;
@@ -118,6 +118,20 @@ export class RuntimeStateStore {
118
118
  session.updatedAt = new Date().toISOString();
119
119
  this.save();
120
120
  }
121
+ setStreamRepliesOverride(senderId, streamReplies) {
122
+ const session = this.mutableActiveSession(senderId);
123
+ if (!session) {
124
+ throw new Error(`No active session for sender: ${senderId}`);
125
+ }
126
+ if (typeof streamReplies === "boolean") {
127
+ session.streamReplies = streamReplies;
128
+ }
129
+ else {
130
+ delete session.streamReplies;
131
+ }
132
+ session.updatedAt = new Date().toISOString();
133
+ this.save();
134
+ }
121
135
  listSessions() {
122
136
  return structuredClone(this.state.sessions)
123
137
  .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
@@ -207,6 +221,12 @@ export class RuntimeStateStore {
207
221
  else
208
222
  delete session.effort;
209
223
  }
224
+ if (Object.hasOwn(overrides, "streamReplies")) {
225
+ if (typeof overrides.streamReplies === "boolean")
226
+ session.streamReplies = overrides.streamReplies;
227
+ else
228
+ delete session.streamReplies;
229
+ }
210
230
  session.updatedAt = new Date().toISOString();
211
231
  this.save();
212
232
  return structuredClone(session);
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-state.js","sourceRoot":"","sources":["../../src/state/runtime-state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime-state.js","sourceRoot":"","sources":["../../src/state/runtime-state.ts"],"names":[],"mappings":"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"}
package/dist/web/app.js CHANGED
@@ -14,12 +14,18 @@ const state = {
14
14
  loadingMessages: false,
15
15
  sendingMessage: false,
16
16
  savingSessionRuntime: false,
17
+ updateInfo: null,
18
+ updateInstalling: false,
17
19
  selectedAccountId: "",
18
20
  chatFiles: []
19
21
  };
20
22
 
21
23
  const MAX_CHAT_FILES = 10;
22
24
  const MAX_CHAT_FILE_BYTES = 50 * 1024 * 1024;
25
+ const DISMISSED_UPDATE_KEY = "codex-weixin.dismissed-update";
26
+ const UPDATE_CHECK_INTERVAL_MS = 6 * 60 * 60 * 1000;
27
+ const UPDATE_RECONNECT_TIMEOUT_MS = 90 * 1000;
28
+ let streamingRenderFrame = 0;
23
29
 
24
30
  const els = {};
25
31
 
@@ -43,12 +49,21 @@ document.addEventListener("DOMContentLoaded", () => {
43
49
  sessionRuntimeToolbar: document.querySelector("#sessionRuntimeToolbar"),
44
50
  sessionModelInput: document.querySelector("#sessionModelInput"),
45
51
  sessionEffortInput: document.querySelector("#sessionEffortInput"),
52
+ sessionStreamInput: document.querySelector("#sessionStreamInput"),
46
53
  runningAccountMetric: document.querySelector("#runningAccountMetric"),
47
54
  sessionMetric: document.querySelector("#sessionMetric"),
48
55
  workspaceMetric: document.querySelector("#workspaceMetric"),
49
56
  qrDialog: document.querySelector("#qrDialog"),
50
57
  qrFrame: document.querySelector("#qrFrame"),
51
58
  qrStatus: document.querySelector("#qrStatus"),
59
+ updateDialog: document.querySelector("#updateDialog"),
60
+ updateCurrentVersion: document.querySelector("#updateCurrentVersion"),
61
+ updateLatestVersion: document.querySelector("#updateLatestVersion"),
62
+ updateProgress: document.querySelector("#updateProgress"),
63
+ updateProgressTitle: document.querySelector("#updateProgressTitle"),
64
+ updateProgressDetail: document.querySelector("#updateProgressDetail"),
65
+ updateLaterButton: document.querySelector("#updateLaterButton"),
66
+ updateNowButton: document.querySelector("#updateNowButton"),
52
67
  accountDialog: document.querySelector("#accountDialog"),
53
68
  sessionDialog: document.querySelector("#sessionDialog")
54
69
  });
@@ -67,6 +82,7 @@ function bindEvents() {
67
82
  document.querySelector("#modelInput").addEventListener("change", () => renderEffortOptions(""));
68
83
  els.sessionModelInput.addEventListener("change", () => void handleSessionModelChange());
69
84
  els.sessionEffortInput.addEventListener("change", () => void saveSessionRuntimeSettings());
85
+ els.sessionStreamInput.addEventListener("change", () => void saveSessionRuntimeSettings());
70
86
  document.querySelector("#accountForm").addEventListener("submit", (event) => void saveAccountRemark(event));
71
87
  document.querySelector("#sessionForm").addEventListener("submit", (event) => void saveSession(event));
72
88
  document.querySelector("#sessionSenderInput").addEventListener("change", updateNewSessionDefaultTitle);
@@ -81,6 +97,12 @@ function bindEvents() {
81
97
  els.sessionsList.addEventListener("click", (event) => void handleSessionAction(event));
82
98
  els.sessionAccountTabs.addEventListener("click", handleSessionAccountTab);
83
99
  els.qrDialog.addEventListener("close", stopLoginPoll);
100
+ els.updateLaterButton.addEventListener("click", dismissUpdate);
101
+ els.updateNowButton.addEventListener("click", () => void installUpdate());
102
+ els.updateDialog.addEventListener("cancel", (event) => {
103
+ event.preventDefault();
104
+ if (!state.updateInstalling) dismissUpdate();
105
+ });
84
106
  window.addEventListener("hashchange", () => showView(location.hash.slice(1) || "accounts", false));
85
107
  }
86
108
 
@@ -98,12 +120,137 @@ async function bootstrap() {
98
120
  renderAll();
99
121
  showView(location.hash.slice(1) || "accounts", false);
100
122
  window.setInterval(() => void refreshData(false), 5000);
123
+ void checkForUpdate();
124
+ window.setInterval(() => void checkForUpdate(), UPDATE_CHECK_INTERVAL_MS);
101
125
  } catch (error) {
102
126
  toast(error.message, true);
103
127
  els.accountsList.innerHTML = emptyState("server-off", "无法连接本机服务", "请重新启动 codex-weixin");
104
128
  }
105
129
  }
106
130
 
131
+ async function checkForUpdate() {
132
+ if (state.updateInstalling) return;
133
+ try {
134
+ const info = await api("/api/update", { token: false });
135
+ if (!info.updateAvailable || !info.latestVersion || dismissedUpdateVersion() === info.latestVersion) {
136
+ return;
137
+ }
138
+ state.updateInfo = info;
139
+ els.updateCurrentVersion.textContent = `v${String(info.currentVersion).replace(/^v/i, "")}`;
140
+ els.updateLatestVersion.textContent = `v${String(info.latestVersion).replace(/^v/i, "")}`;
141
+ resetUpdateDialog();
142
+ if (!els.updateDialog.open) els.updateDialog.showModal();
143
+ drawIcons();
144
+ } catch {
145
+ // Update checks are best-effort and must not interrupt the local management page.
146
+ }
147
+ }
148
+
149
+ function dismissUpdate() {
150
+ if (state.updateInstalling) return;
151
+ const version = state.updateInfo?.latestVersion;
152
+ if (version) {
153
+ try {
154
+ localStorage.setItem(DISMISSED_UPDATE_KEY, version);
155
+ } catch {
156
+ // Dismissing still works when browser storage is unavailable.
157
+ }
158
+ }
159
+ state.updateInfo = null;
160
+ if (els.updateDialog.open) els.updateDialog.close();
161
+ }
162
+
163
+ async function installUpdate() {
164
+ if (state.updateInstalling || !state.updateInfo?.latestVersion) return;
165
+ const previousToken = state.requestToken;
166
+ state.updateInstalling = true;
167
+ els.updateLaterButton.disabled = true;
168
+ els.updateNowButton.disabled = true;
169
+ els.updateNowButton.querySelector("span").textContent = "更新中";
170
+ setUpdateProgress(
171
+ "正在安装更新",
172
+ `正在连接${updateRegistryName(state.updateInfo.registry)},微信服务将继续运行`
173
+ );
174
+ try {
175
+ const result = await api("/api/update", { method: "POST" });
176
+ const targetVersion = result.version;
177
+ state.updateInfo = { ...state.updateInfo, latestVersion: targetVersion, registry: result.registry };
178
+ els.updateLatestVersion.textContent = `v${String(targetVersion).replace(/^v/i, "")}`;
179
+ if (!result.restarting) {
180
+ throw new Error("更新已安装,但自动重启未启动,请手动重启 codex-weixin");
181
+ }
182
+ setUpdateProgress(
183
+ "正在重启服务",
184
+ `已通过${updateRegistryName(result.registry)}完成安装,正在恢复微信连接`
185
+ );
186
+ await waitForUpdatedService(targetVersion, previousToken);
187
+ setUpdateProgress("更新完成", "新版本已启动,正在刷新页面");
188
+ window.location.reload();
189
+ } catch (error) {
190
+ state.updateInstalling = false;
191
+ els.updateLaterButton.disabled = false;
192
+ els.updateNowButton.disabled = false;
193
+ els.updateNowButton.querySelector("span").textContent = "重试更新";
194
+ setUpdateProgress("更新未完成", error.message || "请稍后重试", true);
195
+ }
196
+ }
197
+
198
+ async function waitForUpdatedService(targetVersion, previousToken) {
199
+ const deadline = Date.now() + UPDATE_RECONNECT_TIMEOUT_MS;
200
+ while (Date.now() < deadline) {
201
+ try {
202
+ const response = await fetch("/api/bootstrap", { cache: "no-store" });
203
+ const data = await response.json().catch(() => ({}));
204
+ if (
205
+ response.ok
206
+ && data.version === targetVersion
207
+ && data.requestToken
208
+ && data.requestToken !== previousToken
209
+ ) {
210
+ state.requestToken = data.requestToken;
211
+ state.version = data.version;
212
+ return;
213
+ }
214
+ } catch {
215
+ // The service is expected to be briefly unavailable while it restarts.
216
+ }
217
+ await delay(900);
218
+ }
219
+ throw new Error("新版本已安装,但服务未能自动恢复,请手动重启 codex-weixin");
220
+ }
221
+
222
+ function resetUpdateDialog() {
223
+ state.updateInstalling = false;
224
+ els.updateProgress.hidden = true;
225
+ els.updateProgress.classList.remove("is-error");
226
+ els.updateLaterButton.disabled = false;
227
+ els.updateNowButton.disabled = false;
228
+ els.updateNowButton.querySelector("span").textContent = "立即更新";
229
+ }
230
+
231
+ function setUpdateProgress(title, detail, error = false) {
232
+ els.updateProgress.hidden = false;
233
+ els.updateProgress.classList.toggle("is-error", error);
234
+ els.updateProgressTitle.textContent = title;
235
+ els.updateProgressDetail.textContent = detail;
236
+ }
237
+
238
+ function updateRegistryName(registry) {
239
+ return registry === "npmmirror" ? "国内镜像" : "npm 官方源";
240
+ }
241
+
242
+ function dismissedUpdateVersion() {
243
+ try {
244
+ return localStorage.getItem(DISMISSED_UPDATE_KEY) || "";
245
+ } catch {
246
+ return "";
247
+ }
248
+ }
249
+
250
+ function delay(ms) {
251
+ return new Promise((resolve) => window.setTimeout(resolve, ms));
252
+ }
253
+
107
254
  async function refreshData(notify) {
108
255
  try {
109
256
  const previousSession = selectedSession();
@@ -297,6 +444,7 @@ function renderSettings() {
297
444
  document.querySelector("#allowedWorkspacesInput").value = (state.config.allowedWorkspaces || []).join("\n");
298
445
  document.querySelector("#backendInput").value = state.config.codexBackend || "auto";
299
446
  document.querySelector("#sandboxInput").value = state.config.codexExecSandbox || "";
447
+ document.querySelector("#streamRepliesInput").checked = Boolean(state.config.streamReplies);
300
448
  renderModelOptions();
301
449
  document.querySelector("#effectiveModelValue").textContent = state.codexRuntime?.model || state.config.model || "Codex 默认";
302
450
  document.querySelector("#effectiveEffortValue").textContent = state.codexRuntime?.effort || state.config.effort || "Codex 默认";
@@ -547,23 +695,79 @@ function renderChatPanel() {
547
695
  return;
548
696
  }
549
697
  const renderKey = `messages:${sessionKey(session)}:${responding}:${JSON.stringify(state.sessionMessages)}`;
550
- const html = state.sessionMessages.map((message) => `<article class="chat-message is-${escapeAttr(message.role)}${message.attachments?.length ? " has-attachments" : ""}">
698
+ const html = renderConversationMessages(state.sessionMessages, responding) + (responding ? renderTypingIndicator() : "");
699
+ setChatMessagesHtml(html, renderKey);
700
+ }
701
+
702
+ function renderConversationMessages(messages, responding) {
703
+ const html = [];
704
+ let lastUserCreatedAt;
705
+ let index = 0;
706
+ while (index < messages.length) {
707
+ const message = messages[index];
708
+ if (message.kind === "progress") {
709
+ const progress = [];
710
+ while (index < messages.length && messages[index].kind === "progress") {
711
+ progress.push(messages[index]);
712
+ index += 1;
713
+ }
714
+ const nextMessage = messages[index];
715
+ const active = responding && !nextMessage;
716
+ const completedAt = nextMessage?.role === "assistant"
717
+ ? nextMessage.createdAt
718
+ : progress.at(-1)?.createdAt;
719
+ html.push(renderProgressGroup(progress, lastUserCreatedAt, completedAt, active));
720
+ continue;
721
+ }
722
+ if (message.role === "user") lastUserCreatedAt = message.createdAt;
723
+ html.push(renderChatMessage(message));
724
+ index += 1;
725
+ }
726
+ return html.join("");
727
+ }
728
+
729
+ function renderChatMessage(message) {
730
+ return `<article class="chat-message is-${escapeAttr(message.role)}${message.attachments?.length ? " has-attachments" : ""}">
551
731
  <div class="message-meta"><span>${message.role === "user" ? "你" : "Codex"}</span>${message.createdAt ? `<time datetime="${escapeAttr(message.createdAt)}">${escapeHtml(messageTime(message.createdAt))}</time>` : ""}</div>
552
732
  <div class="message-bubble">${message.text ? renderMarkdown(message.text) : ""}${renderMessageAttachments(message.attachments)}</div>
553
- </article>`).join("") + (responding ? renderTypingIndicator() : "");
554
- setChatMessagesHtml(html, renderKey);
733
+ </article>`;
734
+ }
735
+
736
+ function renderProgressGroup(messages, startedAt, completedAt, active) {
737
+ const duration = formatProcessingDuration(startedAt, active ? new Date().toISOString() : completedAt);
738
+ return `<details class="chat-progress-group"${active ? " open" : ""}>
739
+ <summary>
740
+ <span class="progress-summary-title"><i data-lucide="chevron-right"></i>处理过程</span>
741
+ <span>${active ? "已处理" : "处理用时"} ${escapeHtml(duration)}</span>
742
+ </summary>
743
+ <ol class="progress-list">${messages.map((message) => `<li>${renderMarkdown(message.text)}</li>`).join("")}</ol>
744
+ </details>`;
745
+ }
746
+
747
+ function formatProcessingDuration(startValue, endValue) {
748
+ const start = new Date(startValue || "").getTime();
749
+ const end = new Date(endValue || "").getTime();
750
+ if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return "--";
751
+ const seconds = Math.max(0, Math.round((end - start) / 1000));
752
+ if (seconds < 60) return `${seconds} 秒`;
753
+ const minutes = Math.floor(seconds / 60);
754
+ const remaining = seconds % 60;
755
+ return remaining ? `${minutes} 分 ${remaining} 秒` : `${minutes} 分钟`;
555
756
  }
556
757
 
557
758
  function renderSessionRuntimeControls(session) {
558
759
  const disabled = !session || state.sendingMessage || state.savingSessionRuntime;
559
760
  els.sessionModelInput.disabled = disabled;
560
761
  els.sessionEffortInput.disabled = disabled;
762
+ els.sessionStreamInput.disabled = disabled;
561
763
  const renderKey = session ? [
562
764
  sessionKey(session),
563
765
  session.model || "",
564
766
  session.effort || "",
767
+ typeof session.streamReplies === "boolean" ? String(session.streamReplies) : "inherit",
565
768
  state.config?.model || "",
566
769
  state.config?.effort || "",
770
+ String(Boolean(state.config?.streamReplies)),
567
771
  state.codexRuntime?.model || "",
568
772
  state.codexRuntime?.effort || "",
569
773
  state.codexModels.length
@@ -574,6 +778,7 @@ function renderSessionRuntimeControls(session) {
574
778
  if (!session) {
575
779
  els.sessionModelInput.innerHTML = '<option value="">选择会话后设置</option>';
576
780
  els.sessionEffortInput.innerHTML = '<option value="">选择会话后设置</option>';
781
+ els.sessionStreamInput.innerHTML = '<option value="">选择会话后设置</option>';
577
782
  return;
578
783
  }
579
784
 
@@ -595,6 +800,14 @@ function renderSessionRuntimeControls(session) {
595
800
  els.sessionModelInput.innerHTML = options.map((option) => `<option value="${escapeAttr(option.value)}"${option.title ? ` title="${escapeAttr(option.title)}"` : ""}>${escapeHtml(option.label)}</option>`).join("");
596
801
  els.sessionModelInput.value = session.model || "";
597
802
  setSessionEffortOptions(session.model || "", session.effort || "");
803
+ els.sessionStreamInput.innerHTML = [
804
+ `<option value="">继承全局(${state.config?.streamReplies ? "开启" : "关闭"})</option>`,
805
+ '<option value="on">开启</option>',
806
+ '<option value="off">关闭</option>'
807
+ ].join("");
808
+ els.sessionStreamInput.value = typeof session.streamReplies === "boolean"
809
+ ? session.streamReplies ? "on" : "off"
810
+ : "";
598
811
  }
599
812
 
600
813
  function setSessionEffortOptions(modelOverride, preferredEffort) {
@@ -639,18 +852,23 @@ async function saveSessionRuntimeSettings() {
639
852
  const key = sessionKey(session);
640
853
  const model = els.sessionModelInput.value;
641
854
  const effort = els.sessionEffortInput.value;
855
+ const stream = els.sessionStreamInput.value;
642
856
  state.savingSessionRuntime = true;
643
857
  renderChatPanel();
644
858
  try {
645
859
  const result = await api(`/api/sessions/${encodeURIComponent(session.accountId)}/${encodeURIComponent(session.id)}`, {
646
860
  method: "PATCH",
647
- body: { model: model || null, effort: effort || null }
861
+ body: {
862
+ model: model || null,
863
+ effort: effort || null,
864
+ streamReplies: stream ? stream === "on" : null
865
+ }
648
866
  });
649
867
  const index = state.sessions.findIndex((candidate) => sessionKey(candidate) === key);
650
868
  if (index >= 0) state.sessions[index] = result.session;
651
869
  els.sessionRuntimeToolbar.dataset.renderKey = "";
652
870
  renderSessions();
653
- toast("会话模型设置已更新");
871
+ toast("会话设置已更新");
654
872
  } catch (error) {
655
873
  toast(error.message, true);
656
874
  await refreshData(false);
@@ -715,6 +933,8 @@ async function sendSessionMessage(event) {
715
933
  const files = [...state.chatFiles];
716
934
  if (!session || (!text && !files.length) || state.sendingMessage) return;
717
935
  const key = sessionKey(session);
936
+ const streaming = session.streamReplies ?? Boolean(state.config?.streamReplies);
937
+ let progressSequence = 0;
718
938
  state.sendingMessage = true;
719
939
  state.sessionMessages.push({
720
940
  id: `pending-${Date.now()}`,
@@ -737,10 +957,29 @@ async function sendSessionMessage(event) {
737
957
  const body = new FormData();
738
958
  body.append("text", text);
739
959
  files.forEach((file) => body.append("files", file, file.name));
740
- await api(`/api/sessions/${encodeURIComponent(session.accountId)}/${encodeURIComponent(session.id)}/messages`, {
741
- method: "POST",
742
- body
743
- });
960
+ const url = `/api/sessions/${encodeURIComponent(session.accountId)}/${encodeURIComponent(session.id)}/messages`;
961
+ if (streaming) {
962
+ await streamApi(`${url}?stream=1`, { method: "POST", body }, (streamEvent) => {
963
+ if (state.selectedSessionKey !== key) return;
964
+ if (streamEvent.type === "progress" && streamEvent.message?.trim()) {
965
+ state.sessionMessages.push({
966
+ id: `progress-${Date.now()}-${progressSequence++}`,
967
+ role: "assistant",
968
+ text: streamEvent.message.trim(),
969
+ kind: "progress",
970
+ createdAt: new Date().toISOString(),
971
+ attachments: []
972
+ });
973
+ scheduleStreamingRender();
974
+ }
975
+ if (streamEvent.type === "done" && streamEvent.result?.message) {
976
+ state.sessionMessages.push(streamEvent.result.message);
977
+ scheduleStreamingRender();
978
+ }
979
+ });
980
+ } else {
981
+ await api(url, { method: "POST", body });
982
+ }
744
983
  await refreshData(false);
745
984
  if (state.selectedSessionKey === key) {
746
985
  await loadSelectedSessionMessages();
@@ -759,6 +998,15 @@ async function sendSessionMessage(event) {
759
998
  }
760
999
  }
761
1000
 
1001
+ function scheduleStreamingRender() {
1002
+ if (streamingRenderFrame) return;
1003
+ streamingRenderFrame = requestAnimationFrame(() => {
1004
+ streamingRenderFrame = 0;
1005
+ renderChatPanel();
1006
+ scrollChatToEnd();
1007
+ });
1008
+ }
1009
+
762
1010
  function handleChatFileSelection(event) {
763
1011
  const nextFiles = [...event.target.files];
764
1012
  event.target.value = "";
@@ -971,7 +1219,8 @@ async function saveSettings(event) {
971
1219
  codexBackend: document.querySelector("#backendInput").value,
972
1220
  codexExecSandbox: document.querySelector("#sandboxInput").value || null,
973
1221
  model: document.querySelector("#modelInput").value.trim(),
974
- effort: document.querySelector("#effortInput").value.trim()
1222
+ effort: document.querySelector("#effortInput").value.trim(),
1223
+ streamReplies: document.querySelector("#streamRepliesInput").checked
975
1224
  }
976
1225
  });
977
1226
  state.config = result.config;
@@ -1015,6 +1264,46 @@ async function api(url, options = {}) {
1015
1264
  return data;
1016
1265
  }
1017
1266
 
1267
+ async function streamApi(url, options, onEvent) {
1268
+ const headers = {};
1269
+ if (state.requestToken) headers["X-Codex-Weixin-Token"] = state.requestToken;
1270
+ const response = await fetch(url, {
1271
+ method: options.method || "POST",
1272
+ headers,
1273
+ body: options.body
1274
+ });
1275
+ const contentType = response.headers.get("content-type") || "";
1276
+ if (!contentType.startsWith("application/x-ndjson")) {
1277
+ const data = await response.json().catch(() => ({}));
1278
+ if (!response.ok) throw new Error(data.error || `请求失败 (${response.status})`);
1279
+ return data.result;
1280
+ }
1281
+ if (!response.ok || !response.body) {
1282
+ throw new Error(`请求失败 (${response.status})`);
1283
+ }
1284
+ const reader = response.body.getReader();
1285
+ const decoder = new TextDecoder();
1286
+ let buffer = "";
1287
+ let result;
1288
+ const consumeLine = (line) => {
1289
+ if (!line.trim()) return;
1290
+ const streamEvent = JSON.parse(line);
1291
+ if (streamEvent.type === "error") throw new Error(streamEvent.error || "过程进度失败");
1292
+ onEvent(streamEvent);
1293
+ if (streamEvent.type === "done") result = streamEvent.result;
1294
+ };
1295
+ while (true) {
1296
+ const { value, done } = await reader.read();
1297
+ buffer += decoder.decode(value || new Uint8Array(), { stream: !done });
1298
+ const lines = buffer.split(/\r?\n/);
1299
+ buffer = lines.pop() || "";
1300
+ for (const line of lines) consumeLine(line);
1301
+ if (done) break;
1302
+ }
1303
+ if (buffer) consumeLine(buffer);
1304
+ return result;
1305
+ }
1306
+
1018
1307
  function emptyState(icon, title, description = "", action = "") {
1019
1308
  return `<div class="empty-state"><div class="empty-state-inner"><span class="empty-icon"><i data-lucide="${escapeAttr(icon)}"></i></span><h2>${escapeHtml(title)}</h2>${description ? `<p>${escapeHtml(description)}</p>` : ""}${action}</div></div>`;
1020
1309
  }
@@ -28,10 +28,15 @@
28
28
  <button class="tab" type="button" data-view="sessions">会话</button>
29
29
  <button class="tab" type="button" data-view="settings">设置</button>
30
30
  </nav>
31
- <button class="button button-primary header-action" id="addAccountButton" type="button" title="添加微信" aria-label="添加微信">
32
- <i data-lucide="scan-line"></i>
33
- <span>添加微信</span>
34
- </button>
31
+ <div class="header-actions">
32
+ <a class="icon-button github-link" href="https://github.com/XavierJiezou/codex-weixin" target="_blank" rel="noopener noreferrer" title="前往 GitHub" aria-label="前往 codex-weixin GitHub 仓库">
33
+ <i data-lucide="github"></i>
34
+ </a>
35
+ <button class="button button-primary header-action" id="addAccountButton" type="button" title="添加微信" aria-label="添加微信">
36
+ <i data-lucide="scan-line"></i>
37
+ <span>添加微信</span>
38
+ </button>
39
+ </div>
35
40
  </div>
36
41
  </header>
37
42
 
@@ -104,6 +109,14 @@
104
109
  <span>推理强度</span>
105
110
  <select id="sessionEffortInput" disabled><option value="">继承全局设置</option></select>
106
111
  </label>
112
+ <label>
113
+ <span>过程进度</span>
114
+ <select id="sessionStreamInput" disabled>
115
+ <option value="">继承全局设置</option>
116
+ <option value="on">开启</option>
117
+ <option value="off">关闭</option>
118
+ </select>
119
+ </label>
107
120
  </div>
108
121
  <div class="chat-messages" id="chatMessages" aria-live="polite"></div>
109
122
  <form class="chat-composer" id="chatComposer">
@@ -179,6 +192,13 @@
179
192
  </select>
180
193
  <small class="field-hint effective-setting"><span>当前生效</span><strong id="effectiveEffortValue">正在读取</strong></small>
181
194
  </label>
195
+ <label class="toggle-field" for="streamRepliesInput">
196
+ <span>过程进度</span>
197
+ <span class="toggle-control">
198
+ <input id="streamRepliesInput" name="streamReplies" type="checkbox">
199
+ <span aria-hidden="true"></span>
200
+ </span>
201
+ </label>
182
202
  </div>
183
203
  </div>
184
204
  <div class="form-actions">
@@ -191,6 +211,35 @@
191
211
  </section>
192
212
  </main>
193
213
 
214
+ <dialog class="modal update-modal" id="updateDialog" aria-labelledby="updateDialogTitle">
215
+ <div class="modal-header update-modal-header">
216
+ <div>
217
+ <p class="eyebrow">PRODUCT UPDATE</p>
218
+ <h2 id="updateDialogTitle">发现新版本</h2>
219
+ </div>
220
+ <span class="update-modal-icon" aria-hidden="true"><i data-lucide="package"></i></span>
221
+ </div>
222
+ <div class="modal-body update-modal-body">
223
+ <div class="update-version-flow" aria-label="版本升级">
224
+ <span><small>当前版本</small><strong id="updateCurrentVersion">--</strong></span>
225
+ <i data-lucide="arrow-right" aria-hidden="true"></i>
226
+ <span class="is-latest"><small>最新版本</small><strong id="updateLatestVersion">--</strong></span>
227
+ </div>
228
+ <p class="update-description">更新期间微信连接会短暂中断,完成后服务将自动重启并恢复连接。</p>
229
+ <div class="update-progress" id="updateProgress" aria-live="polite" hidden>
230
+ <span class="spinner" aria-hidden="true"></span>
231
+ <div><strong id="updateProgressTitle">正在安装更新</strong><span id="updateProgressDetail">请保持此页面打开</span></div>
232
+ </div>
233
+ </div>
234
+ <div class="modal-footer">
235
+ <button class="button button-secondary" id="updateLaterButton" type="button">稍后</button>
236
+ <button class="button button-primary" id="updateNowButton" type="button">
237
+ <i data-lucide="download"></i>
238
+ <span>立即更新</span>
239
+ </button>
240
+ </div>
241
+ </dialog>
242
+
194
243
  <dialog class="modal qr-modal" id="qrDialog">
195
244
  <div class="modal-header">
196
245
  <div>