ai_co_discuss 0.2.46 → 0.2.48
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/.agents/skills/discuss-host/SKILL.md +82 -43
- package/.agents/skills/discuss-host/references/launch.md +18 -4
- package/.agents/skills/discuss-participant/SKILL.md +57 -34
- package/.agents/skills/discuss-participant/references/free.md +23 -0
- package/.agents/skills/discuss-participant/references/manual.md +11 -3
- package/backend/free_room.py +20 -10
- package/backend/schema.sql +3 -1
- package/backend/server.py +69 -6
- package/docs/architecture.md +1 -1
- package/docs/cli.md +1 -1
- package/docs/runner.md +1 -1
- package/docs/skills.md +1 -1
- package/docs/workflow.md +169 -169
- package/package.json +1 -1
- package/runner/api_participant.mjs +6 -4
- package/runner/discuss.py +4 -2
- package/runner/discussion_adapters.mjs +3 -2
- package/runner/discussion_launch.mjs +11 -7
- package/runner/discussion_runner.mjs +2 -1
- package/runner/free_runner.mjs +6 -3
- package/web/app.js +23 -13
- package/web/modern.css +1 -1
- package/web/modern.js +1055 -1012
package/web/app.js
CHANGED
|
@@ -716,12 +716,19 @@ function floor_status(room) {
|
|
|
716
716
|
|
|
717
717
|
/** A round completes only after all configured experts have contributed. */
|
|
718
718
|
function progress_round(room) {
|
|
719
|
-
|
|
720
|
-
|
|
719
|
+
const groups = round_groups(room);
|
|
720
|
+
if (!groups) return "轮次待同步";
|
|
721
|
+
const latest = groups.at(-1);
|
|
721
722
|
const participants = Object.keys(room.experts).length;
|
|
722
|
-
|
|
723
|
+
const completed = groups.filter((item) => item.completed).length;
|
|
724
|
+
if (latest && !latest.completed) return `第 ${latest.number} 轮 · ${latest.opinions ?? latest.speakers.length}/${participants} 人已发言`;
|
|
723
725
|
return ["pending", "notified"].includes(room.current_turn?.status)
|
|
724
|
-
? `第 ${
|
|
726
|
+
? `第 ${completed + 1} 轮 · 0/${participants} 人已发言` : `已完成 ${completed} 轮`;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/** Rounds as labelled in the UI: counted by the round budget when the room has one, otherwise by the roster. */
|
|
730
|
+
function round_groups(room) {
|
|
731
|
+
return Array.isArray(room.round_groups) ? room.round_groups : Array.isArray(room.rounds) ? room.rounds : null;
|
|
725
732
|
}
|
|
726
733
|
|
|
727
734
|
/** Describe the designated respondent without claiming that their app is generating. */
|
|
@@ -1527,8 +1534,8 @@ async function submit_room(event, folder_id = null) {
|
|
|
1527
1534
|
const payload = room_creation_payload(folder_id);
|
|
1528
1535
|
const free = payload.mode === "free";
|
|
1529
1536
|
// A discussion can still be created without the local service and started later from the room;
|
|
1530
|
-
// a free room needs the service only for members it wakes.
|
|
1531
|
-
const launching = free ? Object.values(payload.experts).includes("cli") : state.launch.create && state.launch.available;
|
|
1537
|
+
// a free room needs the service only for members it wakes or for smart scheduling.
|
|
1538
|
+
const launching = free ? Object.values(payload.experts).includes("cli") || (state.launch.available && Boolean(creation_launch_options().scheduler)) : state.launch.create && state.launch.available;
|
|
1532
1539
|
if (launching && !state.launch.available) throw new Error("本机唤醒的成员需要连接本机服务;也可改为手动接入或网页代发");
|
|
1533
1540
|
const launch_draft = launching ? creation_launch_options() : null;
|
|
1534
1541
|
const signature = JSON.stringify({ payload, launch_draft });
|
|
@@ -2315,7 +2322,7 @@ async function retry_execution(event_id) {
|
|
|
2315
2322
|
show_toast(`已重新安排 ${execution.participant} 执行,原失败记录保留`);
|
|
2316
2323
|
}
|
|
2317
2324
|
|
|
2318
|
-
/** Skip the selected assignment
|
|
2325
|
+
/** Skip the selected assignment: the user posts a "skipped" answer for the expert, so the plan moves on to the next one like after any answer. */
|
|
2319
2326
|
async function skip_turn() {
|
|
2320
2327
|
const room = state.room;
|
|
2321
2328
|
const turn = room.current_turn;
|
|
@@ -2324,18 +2331,21 @@ async function skip_turn() {
|
|
|
2324
2331
|
const runtime = room.runtime || {};
|
|
2325
2332
|
const resume = runtime.mode === "automatic" && (runtime.status === "paused" || runtime.expired);
|
|
2326
2333
|
const revision = runtime.revision;
|
|
2327
|
-
let
|
|
2334
|
+
let saved = false;
|
|
2328
2335
|
try {
|
|
2329
|
-
|
|
2330
|
-
|
|
2336
|
+
const floor = room.floor;
|
|
2337
|
+
if (floor.holder !== turn.expert) await request_json(`${path}/floor`, { actor: "用户", speaker: turn.expert, action: "take", revision: floor.revision });
|
|
2338
|
+
await request_json(`${path}/messages`, { author: turn.expert, submitted_by: "用户", kind: "opinion", turn_id: turn.id,
|
|
2339
|
+
text: "(本次发言已被用户跳过)", submission_id: new_submission_id() });
|
|
2340
|
+
saved = true;
|
|
2331
2341
|
if (resume) await request_json(`${path}/runtime`, { action: "start", mode: "automatic", revision, deadline: 0 });
|
|
2332
2342
|
} catch (error) {
|
|
2333
|
-
if (
|
|
2343
|
+
if (saved && resume) throw new Error(`本次发言已跳过,但未能继续讨论:${error.message}。核对后可点“重启”继续`);
|
|
2334
2344
|
throw error;
|
|
2335
2345
|
} finally {
|
|
2336
2346
|
if (state.room?.id === room_id) await refresh_room();
|
|
2337
2347
|
}
|
|
2338
|
-
if (state.room?.id === room_id) show_toast(
|
|
2348
|
+
if (state.room?.id === room_id) show_toast("已跳过本次发言,按计划交给下一位");
|
|
2339
2349
|
}
|
|
2340
2350
|
|
|
2341
2351
|
/** Resume the automatic run after a user decision made while paused or just reopened. */
|
|
@@ -3341,7 +3351,7 @@ window.discuss_view = { snapshot: view_snapshot, write_field: write_view_field,
|
|
|
3341
3351
|
update_profile: update_admin_profile, avatar_from_file: admin_avatar_from_file, validate: validate_admin_form },
|
|
3342
3352
|
request: request_json, identities: IDENTITIES, display_name, sources: SOURCE_LABELS, phases: PHASE_LABELS,
|
|
3343
3353
|
runtime_label, execution_label, limits_label, participant_model, participant_access, can_retry_execution,
|
|
3344
|
-
turns: TURN_LABELS, turn_label, turn_guidance, floor_status, progress_round, limit_rounds, progress_speaker, brief_meta, max_message_length: MAX_MESSAGE_LENGTH, provenance: message_provenance, format_time };
|
|
3354
|
+
turns: TURN_LABELS, turn_label, turn_guidance, floor_status, progress_round, round_groups, limit_rounds, progress_speaker, brief_meta, max_message_length: MAX_MESSAGE_LENGTH, provenance: message_provenance, format_time };
|
|
3345
3355
|
|
|
3346
3356
|
restore_theme();
|
|
3347
3357
|
restore_directory_sort();
|