ai_co_discuss 0.2.32 → 0.2.34

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/web/app.js CHANGED
@@ -38,7 +38,7 @@ const PLATFORM_IDENTITIES = {
38
38
  };
39
39
  const IDENTITIES = by_platform(PLATFORM_IDENTITIES, (identity, name) => ({ ...identity, label: name, description: "AI 实例" }));
40
40
  const state = { rooms: [], folders: [], room: null, page: 1, pages: 1, query: "", mention_only: false, free_notice: "", free_error: "",
41
- free_proxy: "", create_parent: null,
41
+ free_proxy: "", create_parent: null, named_followup: false,
42
42
  archive_view: false, directory_sort: "manual", management: null, dragged_room: null, folder_moves: new Map(), folder_version: 0,
43
43
  reply_to: null, turn_reply_to: null, tab: "topic", refresh_version: 0, context_dirty: false, topic_dirty: false,
44
44
  snapshot_id: 0, pending_submission: null, pending_turn: null, pending_room: null, toast_timer: null,
@@ -841,6 +841,7 @@ function reset_create_form() {
841
841
  state.launch.create = true;
842
842
  state.launch.workspace = {};
843
843
  state.launch.scheduler = {};
844
+ state.named_followup = false;
844
845
  state.launch.profiles = JSON.parse(JSON.stringify(state.launch.saved_profiles || {}));
845
846
  Object.values(state.launch.profiles).forEach(fill_api_key);
846
847
  state.launch.notice = "";
@@ -945,7 +946,7 @@ async function invite_member({ name, access, project_access = "read", session_id
945
946
  finish_member_request(room_id, token, record, result);
946
947
  if (state.room?.id === room_id) {
947
948
  state.free_notice = access === "online" ? `${record.member.name} 已加入,阅读通知与真实回答由你或授权主持人转交。`
948
- : access === "manual" ? `${record.member.name} 已加入;点它的“启动指令”复制含凭证的整段说明,粘贴到你要用的 AI 会话即可。`
949
+ : access === "manual" ? `${record.member.name} 已加入;点它的“复制启动指令”,粘贴到你要用的 AI 会话即可。`
949
950
  : record.options?.session_id ? `${record.member.name} 已接入原会话;它工作时请不要在原窗口继续操作。`
950
951
  : state.room.mode === "free" ? `${record.member.name} 已加入,之后点名它即会由本机服务唤醒。`
951
952
  : `${record.member.name} 已加入讨论,主持人会重新安排发言。`;
@@ -1342,7 +1343,7 @@ function room_creation_payload(folder_id) {
1342
1343
  // Free rooms carry their task in the conversation, so no opening brief is sent even if one was typed for a discussion.
1343
1344
  if (element("new-room-kind").value === "free") return { ...common, user_request: "", mode: "free", host: common.host || "用户" };
1344
1345
  return { ...common, mode: "brainstorm", background: element("new-room-background").value,
1345
- boundaries: element("new-room-boundaries").value, runtime_mode: "automatic", limits: read_limits("new-room"),
1346
+ boundaries: element("new-room-boundaries").value, runtime_mode: "automatic", limits: read_limits("new-room"), named_followup: state.named_followup,
1346
1347
  ...(state.create_parent ? { parent_room_id: state.create_parent } : {}) };
1347
1348
  }
1348
1349
 
@@ -1436,8 +1437,8 @@ async function local_launch_request(action, payload) {
1436
1437
  response = await fetch(`${local_connection?.endpoint || ""}/api/local/${action}`, {
1437
1438
  method: payload === undefined ? "GET" : "POST", headers, credentials: "omit", redirect: "error",
1438
1439
  body: payload === undefined ? undefined : JSON.stringify(payload),
1439
- ...(payload === undefined || ["room-models", "models", "api-check"].includes(action)
1440
- ? { signal: AbortSignal.timeout(["models", "api-check"].includes(action) ? MODEL_CATALOG_TIMEOUT_MS : LOCAL_CONNECTION_TIMEOUT_MS) } : {}) });
1440
+ ...(payload === undefined || ["room-models", "models", "api-check", "scheduler-check"].includes(action)
1441
+ ? { signal: AbortSignal.timeout(["models", "api-check", "scheduler-check"].includes(action) ? MODEL_CATALOG_TIMEOUT_MS : LOCAL_CONNECTION_TIMEOUT_MS) } : {}) });
1441
1442
  } catch (error) {
1442
1443
  if (!local_connection) throw error;
1443
1444
  throw new Error("无法连接本机服务:请在这台电脑运行 codiscuss local open,并允许浏览器访问本机网络,再重试原请求");
@@ -1758,6 +1759,12 @@ function creation_launch_options() {
1758
1759
  return { ...launch_options(), ...(enabled && provider && model && api_key_ref ? { scheduler: { provider, model, api_key_ref } } : {}) };
1759
1760
  }
1760
1761
 
1762
+ /** Choose whether the new discussion's host writes named follow-ups for each expert between rounds. */
1763
+ function write_named_followup(value) {
1764
+ state.named_followup = Boolean(value);
1765
+ publish_view();
1766
+ }
1767
+
1761
1768
  /** Change the smart scheduling draft; a new provider starts from its preset model and any key saved for its root. */
1762
1769
  function write_scheduler(field, value) {
1763
1770
  const scheduler = state.launch.scheduler;
@@ -1771,6 +1778,12 @@ function write_scheduler(field, value) {
1771
1778
  publish_view();
1772
1779
  }
1773
1780
 
1781
+ /** Ask the local service to send the decision model one tiny question; throws its reason on failure. */
1782
+ async function check_scheduler() {
1783
+ const { provider, model, api_key_ref } = state.launch.scheduler;
1784
+ await local_launch_request("scheduler-check", { provider, model, api_key_ref });
1785
+ }
1786
+
1774
1787
  /** Save the scheduling provider's key to the local private store, under that provider's official root. */
1775
1788
  async function save_scheduler_api_key(api_key) {
1776
1789
  const scheduler = state.launch.scheduler;
@@ -2193,7 +2206,7 @@ ${instruction}
2193
2206
  /** How a manual member learns it is its turn: free rooms are pulled by the member, discussions only on the host's assignment. */
2194
2207
  function manual_trigger_instruction(room) {
2195
2208
  return room.mode === "free" ? "首次复制后,可由人工或软件原生定时触发;自行提交,不必每轮复制回答。"
2196
- : "这是全自动讨论:只在主持人给你安排发言时才参与,先核对 turn current 是否轮到你,再按参与技能认领发言权并提交;没有安排就结束本次检查。你不会被自动唤醒,需要你或软件原生定时触发。";
2209
+ : "这是全自动讨论:只在主持人给你安排发言时才参与,先核对 turn current 是否轮到你,再按参与技能认领发言权并提交;没有安排就结束本次检查。首次提交后,若你运行在 Claude Code 中,本机服务会自动接管你的会话并在后续轮次唤醒你;未被接管时才需要你或软件原生定时触发。";
2197
2210
  }
2198
2211
 
2199
2212
  /** Download a private per-room setup file for the independent local runner. */
@@ -2260,6 +2273,13 @@ async function convert_suggestion({ message_id, member_id }) {
2260
2273
  await refresh_room();
2261
2274
  }
2262
2275
 
2276
+ /** Adopt smart scheduling's recommendation: interrupt the host now, or ask the member once the host is done. */
2277
+ async function adopt_recommendation({ message_id, mode }) {
2278
+ const room_id = state.room.id;
2279
+ await request_json(`/api/rooms/${room_id}/recommendations/${message_id}`, { action: "adopt", mode });
2280
+ if (state.room?.id === room_id) await refresh_room();
2281
+ }
2282
+
2263
2283
  /** A completed creation starts the next form with fresh mode defaults. */
2264
2284
  function reset_creation_mode() {
2265
2285
  state.creation_mode = "brainstorm";
@@ -2869,7 +2889,7 @@ function view_snapshot() {
2869
2889
  free_notice: state.free_notice, free_error: state.free_error, free_proxy: state.free_proxy,
2870
2890
  create_parent: state.create_parent, access: access_snapshot(),
2871
2891
  tab: state.tab, snapshot_id: state.snapshot_id, context_dirty: state.context_dirty,
2872
- theme: document.documentElement.dataset.theme, fields, experts, launch: structuredClone(state.launch) };
2892
+ theme: document.documentElement.dataset.theme, fields, experts, launch: structuredClone(state.launch), named_followup: state.named_followup };
2873
2893
  }
2874
2894
 
2875
2895
  /** Update a shared draft using the same input events as the original controls. */
@@ -3041,7 +3061,7 @@ async function execute_view_action(name, value) {
3041
3061
  choose_runtime, export_runtime, download_member_access, copy_member_access_text, copy_member_join, copy_member_launch: name => copy_member_join(name, true), pause_runtime, check_limits, pause_discussion, restart_discussion, force_close, conclude_discussion,
3042
3062
  save_launch_defaults, launch_current_room, resume_launch, discard_launch, retry_launch_connection, check_launch_connection: load_launch_settings,
3043
3063
  load_room_configuration, save_room_configuration, interrupt_member, change_member, invite_member, interrupt_free, set_proxy, copy_online_notice,
3044
- prepare_brainstorm, return_conclusion, convert_suggestion,
3064
+ prepare_brainstorm, return_conclusion, convert_suggestion, adopt_recommendation,
3045
3065
  busy: () => { throw new Error("上一个操作仍在处理中,请稍候;长时间无响应请刷新页面"); },
3046
3066
  copy_reading: () => copy_text(`${location.origin}/r/${state.room.id}`), copy: copy_text };
3047
3067
  if (!["refresh", "busy"].includes(name)) state.free_error = "";
@@ -3064,7 +3084,7 @@ function change_view_theme(theme) {
3064
3084
 
3065
3085
  window.discuss_view = { snapshot: view_snapshot, write_field: write_view_field,
3066
3086
  write_launch: write_launch_field, write_room_connection, write_room_adapter, launch_clients: LAUNCH_CLIENTS,
3067
- launch_model_state, load_launch_models, write_launch_model, save_launch_api_key, write_scheduler, save_scheduler_api_key, check_launch_api, launch_summary, launch_can_set_access, launch_can_bind_session, pick_launch_directory, restore_launch_profile, reset_create_form, empty_discussion_message,
3087
+ launch_model_state, load_launch_models, write_launch_model, save_launch_api_key, write_scheduler, save_scheduler_api_key, check_scheduler, write_named_followup, check_launch_api, launch_summary, launch_can_set_access, launch_can_bind_session, pick_launch_directory, restore_launch_profile, reset_create_form, empty_discussion_message,
3068
3088
  start_drag: start_directory_drag,
3069
3089
  attachment_markup, attachment_size, attachment_file_icon, drop_attachments, paste_attachments,
3070
3090
  write_expert: write_view_expert, add_instance: add_view_instance, platform_of, execute: execute_view_action, theme: change_view_theme,