ai_co_discuss 0.2.48 → 0.2.49
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 +10 -14
- package/.agents/skills/discuss-host/references/launch.md +1 -1
- package/.agents/skills/discuss-host/references/manual.md +5 -5
- package/.agents/skills/discuss-participant/SKILL.md +11 -12
- package/.agents/skills/discuss-participant/references/free.md +1 -1
- package/.agents/skills/discuss-participant/references/manual.md +2 -2
- package/.agents/skills/discuss-participant/references/writing.md +6 -11
- package/README.md +7 -9
- package/backend/free_room.py +39 -70
- package/backend/room_import.py +1 -5
- package/backend/runtime.py +21 -35
- package/backend/schema.sql +52 -60
- package/backend/server.py +130 -141
- package/docs/architecture.md +14 -12
- package/docs/cli.md +12 -21
- package/docs/deployment.md +2 -2
- package/docs/runner.md +8 -6
- package/docs/skills.md +3 -3
- package/docs/workflow.md +22 -40
- package/package.json +1 -1
- package/runner/api_participant.mjs +1 -11
- package/runner/codiscuss.mjs +0 -1
- package/runner/discuss.py +19 -37
- package/runner/discussion_adapters.mjs +1 -1
- package/runner/discussion_runner.mjs +1 -2
- package/runner/discussion_service.mjs +46 -1
- package/runner/free_runner.mjs +4 -3
- package/web/app.js +71 -77
- package/web/backup.js +1 -1
- package/web/index.html +5 -7
- package/web/modern.css +1 -1
- package/web/modern.js +1758 -1886
package/backend/schema.sql
CHANGED
|
@@ -144,27 +144,9 @@ CREATE TABLE IF NOT EXISTS room_floor (
|
|
|
144
144
|
next_speaker TEXT NOT NULL,
|
|
145
145
|
revision INTEGER NOT NULL DEFAULT 0
|
|
146
146
|
);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
FROM rooms LEFT JOIN topic_settings AS settings ON settings.room_id=rooms.id
|
|
151
|
-
LEFT JOIN discussion_turns AS turns ON turns.room_id=rooms.id AND turns.status IN ('pending','notified');
|
|
152
|
-
CREATE TRIGGER IF NOT EXISTS initialize_room_floor AFTER INSERT ON topic_settings
|
|
153
|
-
BEGIN
|
|
154
|
-
INSERT INTO room_floor (room_id,holder,next_speaker) VALUES (NEW.room_id,NEW.host,NEW.host)
|
|
155
|
-
ON CONFLICT(room_id) DO UPDATE SET
|
|
156
|
-
holder=CASE WHEN holder='用户' THEN NEW.host ELSE holder END,
|
|
157
|
-
next_speaker=CASE WHEN next_speaker='用户' THEN NEW.host ELSE next_speaker END,
|
|
158
|
-
revision=revision+1;
|
|
159
|
-
END;
|
|
160
|
-
CREATE TRIGGER IF NOT EXISTS transfer_host_floor AFTER UPDATE OF host ON topic_settings
|
|
161
|
-
WHEN OLD.host<>NEW.host
|
|
162
|
-
BEGIN
|
|
163
|
-
UPDATE room_floor SET holder=CASE WHEN holder=OLD.host THEN NEW.host ELSE holder END,
|
|
164
|
-
next_speaker=CASE WHEN next_speaker=OLD.host THEN NEW.host ELSE next_speaker END,
|
|
165
|
-
revision=revision+1 WHERE room_id=NEW.room_id
|
|
166
|
-
AND NOT EXISTS (SELECT 1 FROM discussion_turns WHERE room_id=NEW.room_id AND status IN ('pending','notified') AND expert=OLD.host);
|
|
167
|
-
END;
|
|
147
|
+
-- The speaking floor is retired: the table stays only so old databases and backups load, and nothing reads or writes it.
|
|
148
|
+
DROP TRIGGER IF EXISTS initialize_room_floor;
|
|
149
|
+
DROP TRIGGER IF EXISTS transfer_host_floor;
|
|
168
150
|
-- Site administrator account (single user) and its login sessions. Raw tokens and passwords are never stored.
|
|
169
151
|
CREATE TABLE IF NOT EXISTS site_admin (
|
|
170
152
|
id INTEGER PRIMARY KEY CHECK(id=1),
|
|
@@ -186,16 +168,12 @@ CREATE TABLE IF NOT EXISTS room_modes (
|
|
|
186
168
|
mode TEXT NOT NULL CHECK(mode IN ('free','brainstorm')),
|
|
187
169
|
control_hash TEXT NOT NULL DEFAULT ''
|
|
188
170
|
);
|
|
189
|
-
-- Replaced on every start so existing databases drop
|
|
171
|
+
-- Replaced on every start so existing databases drop every speaking-floor rule.
|
|
190
172
|
DROP TRIGGER IF EXISTS require_message_floor;
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
AND NOT EXISTS (SELECT 1 FROM room_modes WHERE room_id=NEW.room_id AND mode='free')
|
|
196
|
-
BEGIN
|
|
197
|
-
SELECT RAISE(ABORT, 'floor_required');
|
|
198
|
-
END;
|
|
173
|
+
DROP TRIGGER IF EXISTS return_message_floor;
|
|
174
|
+
DROP TRIGGER IF EXISTS require_host_floor;
|
|
175
|
+
DROP TRIGGER IF EXISTS nominate_expert_floor;
|
|
176
|
+
DROP TRIGGER IF EXISTS cancel_turn_floor;
|
|
199
177
|
CREATE TRIGGER IF NOT EXISTS require_opinion_turn BEFORE INSERT ON message_details
|
|
200
178
|
WHEN NEW.kind='opinion' AND NEW.turn_id IS NULL
|
|
201
179
|
AND NOT EXISTS (SELECT 1 FROM message_details WHERE message_id=NEW.message_id)
|
|
@@ -203,35 +181,6 @@ WHEN NEW.kind='opinion' AND NEW.turn_id IS NULL
|
|
|
203
181
|
BEGIN
|
|
204
182
|
SELECT RAISE(ABORT, 'floor_turn_required');
|
|
205
183
|
END;
|
|
206
|
-
CREATE TRIGGER IF NOT EXISTS return_message_floor AFTER INSERT ON message_details
|
|
207
|
-
WHEN EXISTS (SELECT 1 FROM messages WHERE id=NEW.message_id AND author<>'用户')
|
|
208
|
-
BEGIN
|
|
209
|
-
UPDATE room_floor SET holder=NULL,
|
|
210
|
-
next_speaker=COALESCE((SELECT host FROM topic_settings WHERE room_id=room_floor.room_id),'用户'),
|
|
211
|
-
revision=revision+1 WHERE room_id=(SELECT room_id FROM messages WHERE id=NEW.message_id);
|
|
212
|
-
END;
|
|
213
|
-
DROP TRIGGER IF EXISTS require_host_floor;
|
|
214
|
-
-- Queued turns of a round plan are inserted after the first one has already nominated an expert.
|
|
215
|
-
CREATE TRIGGER require_host_floor BEFORE INSERT ON discussion_turns
|
|
216
|
-
WHEN NEW.status<>'queued' AND NOT EXISTS (SELECT 1 FROM discussion_turns WHERE room_id=NEW.room_id AND submission_id=NEW.submission_id)
|
|
217
|
-
AND NOT EXISTS (SELECT 1 FROM room_floor WHERE room_id=NEW.room_id
|
|
218
|
-
AND holder=COALESCE((SELECT host FROM topic_settings WHERE room_id=NEW.room_id),'用户'))
|
|
219
|
-
BEGIN
|
|
220
|
-
SELECT RAISE(ABORT, 'floor_required');
|
|
221
|
-
END;
|
|
222
|
-
DROP TRIGGER IF EXISTS nominate_expert_floor;
|
|
223
|
-
CREATE TRIGGER nominate_expert_floor AFTER INSERT ON discussion_turns
|
|
224
|
-
WHEN NEW.status<>'queued'
|
|
225
|
-
BEGIN
|
|
226
|
-
UPDATE room_floor SET holder=NULL,next_speaker=NEW.expert,revision=revision+1 WHERE room_id=NEW.room_id;
|
|
227
|
-
END;
|
|
228
|
-
CREATE TRIGGER IF NOT EXISTS cancel_turn_floor AFTER UPDATE OF status ON discussion_turns
|
|
229
|
-
WHEN NEW.status='cancelled' AND OLD.status<>NEW.status
|
|
230
|
-
BEGIN
|
|
231
|
-
UPDATE room_floor SET holder=NULL,
|
|
232
|
-
next_speaker=COALESCE((SELECT host FROM topic_settings WHERE room_id=NEW.room_id),'用户'),
|
|
233
|
-
revision=revision+1 WHERE room_id=NEW.room_id;
|
|
234
|
-
END;
|
|
235
184
|
|
|
236
185
|
-- Runtime control is opt-in. Legacy rooms have no runtime row and keep manual entry.
|
|
237
186
|
CREATE TABLE IF NOT EXISTS discussion_limits (
|
|
@@ -369,7 +318,6 @@ DROP TRIGGER IF EXISTS relay_turn_promoted;
|
|
|
369
318
|
CREATE TRIGGER relay_turn_promoted AFTER UPDATE OF status ON discussion_turns
|
|
370
319
|
WHEN OLD.status='queued' AND NEW.status='pending'
|
|
371
320
|
BEGIN
|
|
372
|
-
UPDATE room_floor SET holder=NULL,next_speaker=NEW.expert,revision=revision+1 WHERE room_id=NEW.room_id;
|
|
373
321
|
UPDATE turn_relay SET held_since=0 WHERE room_id=NEW.room_id
|
|
374
322
|
AND NOT EXISTS(SELECT 1 FROM messages m JOIN discussion_events e ON e.room_id=m.room_id AND e.role='host' AND e.status='started'
|
|
375
323
|
WHERE m.room_id=NEW.room_id AND m.author='用户' AND CAST(strftime('%s',m.created_at) AS INTEGER)>e.started_at);
|
|
@@ -679,3 +627,47 @@ CREATE TABLE IF NOT EXISTS room_links (
|
|
|
679
627
|
parent_id TEXT NOT NULL,
|
|
680
628
|
created_at TEXT NOT NULL
|
|
681
629
|
);
|
|
630
|
+
|
|
631
|
+
-- A discussion is a switch on a room, not a room type: one thin session per started discussion. Its status mirrors the legacy
|
|
632
|
+
-- topic phase until the phase machinery is retired. Free rooms have none.
|
|
633
|
+
CREATE TABLE IF NOT EXISTS discussion_sessions (
|
|
634
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
635
|
+
room_id TEXT NOT NULL REFERENCES rooms(id) ON DELETE CASCADE,
|
|
636
|
+
goal TEXT NOT NULL,
|
|
637
|
+
status TEXT NOT NULL DEFAULT 'paused' CHECK(status IN ('active','paused','concluded')),
|
|
638
|
+
started_message_id INTEGER NOT NULL DEFAULT 0,
|
|
639
|
+
ended_message_id INTEGER NOT NULL DEFAULT 0,
|
|
640
|
+
created_at TEXT NOT NULL
|
|
641
|
+
);
|
|
642
|
+
CREATE UNIQUE INDEX IF NOT EXISTS one_open_session ON discussion_sessions(room_id) WHERE status IN ('active','paused');
|
|
643
|
+
-- Rooms that predate sessions: every non-free room with topic settings gets one, mapped from its phase. Safe to repeat.
|
|
644
|
+
INSERT INTO discussion_sessions (room_id,goal,status,started_message_id,ended_message_id,created_at)
|
|
645
|
+
SELECT rooms.id,rooms.goal,
|
|
646
|
+
CASE WHEN topic_settings.phase='concluded' THEN 'concluded' WHEN topic_settings.phase IN ('preparing','paused') THEN 'paused' ELSE 'active' END,
|
|
647
|
+
0,CASE WHEN topic_settings.phase='concluded' THEN COALESCE((SELECT MAX(id) FROM messages WHERE room_id=rooms.id),0) ELSE 0 END,rooms.created_at
|
|
648
|
+
FROM rooms JOIN topic_settings ON topic_settings.room_id=rooms.id
|
|
649
|
+
WHERE NOT EXISTS (SELECT 1 FROM room_modes WHERE room_id=rooms.id AND mode='free')
|
|
650
|
+
AND NOT EXISTS (SELECT 1 FROM discussion_sessions WHERE room_id=rooms.id);
|
|
651
|
+
DROP TRIGGER IF EXISTS session_for_new_discussion;
|
|
652
|
+
CREATE TRIGGER session_for_new_discussion AFTER INSERT ON room_modes
|
|
653
|
+
WHEN NEW.mode='brainstorm' AND NOT EXISTS (SELECT 1 FROM discussion_sessions WHERE room_id=NEW.room_id)
|
|
654
|
+
BEGIN
|
|
655
|
+
INSERT INTO discussion_sessions (room_id,goal,status,created_at)
|
|
656
|
+
SELECT rooms.id,rooms.goal,
|
|
657
|
+
COALESCE((SELECT CASE WHEN phase='concluded' THEN 'concluded' WHEN phase IN ('preparing','paused') THEN 'paused' ELSE 'active' END
|
|
658
|
+
FROM topic_settings WHERE room_id=rooms.id),'paused'),rooms.created_at
|
|
659
|
+
FROM rooms WHERE rooms.id=NEW.room_id;
|
|
660
|
+
END;
|
|
661
|
+
DROP TRIGGER IF EXISTS session_follows_phase_insert;
|
|
662
|
+
CREATE TRIGGER session_follows_phase_insert AFTER INSERT ON topic_settings
|
|
663
|
+
BEGIN
|
|
664
|
+
UPDATE discussion_sessions SET status=CASE WHEN NEW.phase='concluded' THEN 'concluded' WHEN NEW.phase IN ('preparing','paused') THEN 'paused' ELSE 'active' END
|
|
665
|
+
WHERE id=(SELECT MAX(id) FROM discussion_sessions WHERE room_id=NEW.room_id);
|
|
666
|
+
END;
|
|
667
|
+
DROP TRIGGER IF EXISTS session_follows_phase;
|
|
668
|
+
CREATE TRIGGER session_follows_phase AFTER UPDATE OF phase ON topic_settings
|
|
669
|
+
BEGIN
|
|
670
|
+
UPDATE discussion_sessions SET status=CASE WHEN NEW.phase='concluded' THEN 'concluded' WHEN NEW.phase IN ('preparing','paused') THEN 'paused' ELSE 'active' END,
|
|
671
|
+
ended_message_id=CASE WHEN NEW.phase='concluded' THEN COALESCE((SELECT MAX(id) FROM messages WHERE room_id=NEW.room_id),0) ELSE 0 END
|
|
672
|
+
WHERE id=(SELECT MAX(id) FROM discussion_sessions WHERE room_id=NEW.room_id);
|
|
673
|
+
END;
|