ai_co_discuss 0.2.2 → 0.2.4
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 +1 -1
- package/docs/architecture.md +1 -1
- package/docs/runner.md +2 -2
- package/package.json +1 -1
- package/runner/discussion_launch.mjs +23 -1
- package/web/app.js +1 -1
- package/web/modern.css +1 -1
- package/web/modern.js +500 -486
package/README.md
CHANGED
|
@@ -63,7 +63,7 @@ codiscuss setup
|
|
|
63
63
|
|
|
64
64
|
1. 安装完成后进入自动打开的网站;以后运行 `codiscuss local open` 打开或复用本机网站,默认地址为 `http://127.0.0.1:8765`。
|
|
65
65
|
2. 点击“新建讨论”,填写**话题名称**和**用户原文**。把问题、背景与顾虑写在原文中,讨论目标、背景和边界由 AI 主持人据此补全。
|
|
66
|
-
3.
|
|
66
|
+
3. 房间用法选择“头脑风暴”,接入方式选择“程序唤醒”,从卡片下方的“添加”行加入本场专家,点卡片上的皇冠指定 AI 主持人,点击“移出”调整名单。自动 CLI 卡片背面从真实软件目录下拉选择模型,并按模型支持的档位设置思考强度;留空使用 CLI 默认值,App 在原软件设置。分别设置轮次和时长上限,点击数值展开滚轮或直接输入。新建默认 **3 轮 / 不限时长**,按轮次上限或手动停止结束;单次 AI 执行也默认不限时,可按需设置 1–60 分钟上限。
|
|
67
67
|
4. 勾选“创建后立即启动 AI”,复核软件配置。需要修改时展开“调整启动配置”;未配置的软件需选择 CLI / App 类型并补齐路径。项目目录、读写权限和已有会话按本场需要填写。
|
|
68
68
|
5. 点击“创建并启动讨论”。程序完成建房、登记与首次任务交付;在进度看板核对 AI 是否实际进入,并查看保存的发言。
|
|
69
69
|
|
package/docs/architecture.md
CHANGED
|
@@ -148,7 +148,7 @@ Python 在一个只读事务快照中查询;D1 使用同一个 batch 事务读
|
|
|
148
148
|
|
|
149
149
|
### 主题与交互边界
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
新建表单独立选择房间用法(头脑风暴/自由协作)与接入方式(程序唤醒/手动),共用内联角色库。接入方式以分段切换放在参与区标题旁;每次添加生成独立实例,已加入成员以 `ExpertCard.vue` 渲染为翻面卡片:正面是身份与只读配置(状态、软件、模型、强度),背面是设置;卡片上的皇冠指定主持人,移出按钮同步修复主持人选择,角色库为卡片下方的“添加”标签行。自由协作默认用户主持(“我来主持”),可改由一位本地 AI 主持。支持本地参与的卡片翻面设置参与能力和软件入口,纯网页角色不翻面。自动 CLI 从本机软件目录下拉选择模型,不要求手填 ID;模型与强度同层显示,恢复默认只清除当前实例覆盖。App、网页和手动会话在原软件内设置。`EffortSlider.vue` 按所选模型的实际档位显示,首档为空值的 CLI 默认,显示标签与提交值分离(Extra High 对应 xhigh);agy 的强度随模型,不另显示滑杆。目录不可用时显示原因并保留软件默认,不虚构列表。
|
|
152
152
|
|
|
153
153
|
正反面占用同一网格单元,避免翻转引起布局跳动。角度由现有 Motion 弹簧驱动:质量 1、频率 2.615 Hz、阻尼比 0.96(刚度 270.032、阻尼 31.551);目标在 0° / 180° 之间切换,中途反向保留速度,无固定时长。隐藏面设为 inert 并退出辅助技术读取,转过 90° 后移交焦点;Escape 返回,减少动态效果时直接到位。滑块采用单位质量、4.5 Hz 临界阻尼弹簧,拖动由 6 Hz 手部弹簧牵引、8 Hz 端点力限制;松手依据真实位置与速度的投影选择档位,点击直接选档,方向键和 Home / End 覆盖全部档位,取消拖动恢复原选项。模型与强度仅在创建前配置,讨论进度中保持只读。
|
|
154
154
|
|
package/docs/runner.md
CHANGED
|
@@ -69,7 +69,7 @@ Windows 的 MSIX 应用(如 Claude 桌面版)可能把派生进程对 AppDat
|
|
|
69
69
|
python server.py --host 127.0.0.1 --local-launch
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
需要 Node.js 24+ 与已安装、已登录的 AI 客户端;讨论所需的最小工具权限按 [单次执行权限](#单次执行权限)
|
|
72
|
+
需要 Node.js 24+ 与已安装、已登录的 AI 客户端;讨论所需的最小工具权限按 [单次执行权限](#单次执行权限) 提供。新建时分别选择房间用法与“程序唤醒”,从卡片下方的“添加”行加入本地参与实例,点卡片上的皇冠指定主持人;自由协作默认用户主持,头脑风暴须选择本地 AI 主持。参与区只显示已加入的实例,用独立“移出”按钮调整名单。自动 CLI 卡片翻到背面后通过真实软件目录下拉选择模型,并按该模型支持的档位显示强度滑杆;首档使用 CLI 默认,agy 的强度包含在模型 ID 中。恢复默认只清除该实例的模型与强度覆盖,App、网页和手动会话在原软件设置。配置入口不依赖勾选立即启动,移出后重新加入保留本次填写。头脑风暴可勾选“创建后立即启动 AI”,按需填写项目目录与项目文件权限(默认只读),再点击“创建并启动讨论”;不勾选则只建房,之后在“接入”页启动。自由协作的“创建并连接”登记自动成员,后续点名产生任务时才唤醒。配置可“保存为本机软件默认配置”,保存本身不启动任何 AI。卡片输入沿用当前页面的启动草稿,不随只建房请求保存到网站。正常首次自动接入无需下载 JSON、手动登记房间或另执行 `run start`。
|
|
73
73
|
|
|
74
74
|
网页在发送前把完整已提交输入、原提交号和控制凭据保存在当前站点的浏览器本地存储。服务启动失败或响应丢失后,刷新仍会显示“继续未完成的启动”;点击“继续本次启动”沿用原请求和本机已固定配置,无需重新填写,也不随新的默认配置变化。刷新只恢复界面,不自动运行;已暂停、结束、过期或在启动期间改变的房间不会因此重新开始。部分失败明确显示已核实的阶段,已建房不等于回滚;结果不明时保留原请求待核对。
|
|
75
75
|
|
|
@@ -77,7 +77,7 @@ python server.py --host 127.0.0.1 --local-launch
|
|
|
77
77
|
|
|
78
78
|
### 本机模型目录
|
|
79
79
|
|
|
80
|
-
网页的自动 CLI 模型选择通过 `POST /api/local/models` 读取本机软件目录。输入为 `adapter`、可选完整 `executable`;未传路径时沿用该适配器的本机配置。CLI 对应 `codiscuss launch models --file FILE`。返回 `{adapter, models:[{id,label,efforts?}], source, error?}`,只含模型元数据;没有列表时显示原因并允许使用软件默认,不要求手填 ID
|
|
80
|
+
网页的自动 CLI 模型选择通过 `POST /api/local/models` 读取本机软件目录。输入为 `adapter`、可选完整 `executable`;未传路径时沿用该适配器的本机配置。CLI 对应 `codiscuss launch models --file FILE`。返回 `{adapter, models:[{id,label,efforts?}], source, error?}`,只含模型元数据;没有列表时显示原因并允许使用软件默认,不要求手填 ID。部分 CLI 列表较慢(`agy models` 实测约 15 秒),本机服务把成功结果按适配器、路径与可执行文件大小/修改时间缓存在服务目录的 `model-catalogs.json`,24 小时内复用;可执行文件变化或点“重试”(`refresh: true`)时重新查询,查询失败不覆盖上次成功的列表。卡片加入后即在后台预读,不等翻面;页面同样按适配器和路径缓存,模型支持的档位随目录返回;App、纯网页和手动会话在原软件设置。
|
|
81
81
|
|
|
82
82
|
- Codex:临时运行 `app-server`,依次 `initialize`、`initialized`、分页 `model/list`,不创建 thread 或 turn。见 [官方协议](https://learn.chatgpt.com/docs/app-server#list-models-modellist)。
|
|
83
83
|
- Claude:临时以 `--safe-mode --no-session-persistence` 开启流式控制通道,仅发送 initialize,读取软件返回的 models 和 supportedEffortLevels;禁用自定义启动扩展,不发送用户消息。协议依据 [官方客户端初始化](https://github.com/anthropics/claude-agent-sdk-python/blob/main/src/claude_agent_sdk/_internal/query.py)。旧版本不支持时显示查询失败。
|
package/package.json
CHANGED
|
@@ -52,6 +52,28 @@ conversation 还须 current_session_id,当前会话接手首个主持任务。
|
|
|
52
52
|
详见 docs/runner.md 的“两种讨论入口与启动配置”。
|
|
53
53
|
`;
|
|
54
54
|
|
|
55
|
+
/** Some CLIs take seconds to list models; reuse a good list for a day unless the executable changes or the user retries. */
|
|
56
|
+
const MODEL_CACHE_MS = 24 * 60 * 60 * 1000;
|
|
57
|
+
|
|
58
|
+
/** Return the software catalog, served from the private service home when still valid. */
|
|
59
|
+
export async function cached_software_models(home, profile, { refresh = false, query = software_models } = {}) {
|
|
60
|
+
const path = join(home, 'model-catalogs.json');
|
|
61
|
+
let stamp = '';
|
|
62
|
+
try { const file = statSync(profile.executable); stamp = `${file.size}:${file.mtimeMs}`; } catch {}
|
|
63
|
+
const key = JSON.stringify([profile.adapter, profile.executable || '', stamp]);
|
|
64
|
+
let cache = {};
|
|
65
|
+
try { cache = JSON.parse(readFileSync(path, 'utf8')); } catch {}
|
|
66
|
+
const hit = cache[key];
|
|
67
|
+
if (!refresh && hit && Date.now() - hit.at < MODEL_CACHE_MS) return hit.result;
|
|
68
|
+
const result = await query(profile);
|
|
69
|
+
if (!result.error && result.models.length) {
|
|
70
|
+
const prefix = JSON.stringify([profile.adapter, profile.executable || '']).slice(0, -1);
|
|
71
|
+
for (const old of Object.keys(cache)) if (old.startsWith(prefix)) delete cache[old];
|
|
72
|
+
atomic_json(path, { ...cache, [key]: { at: Date.now(), result } });
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
|
|
55
77
|
/** Read private defaults without selecting a global room or identity. */
|
|
56
78
|
export function launch_settings(home) {
|
|
57
79
|
const path = join(home, 'launch-settings.json');
|
|
@@ -585,7 +607,7 @@ export async function launch_main(args = process.argv.slice(2), input_text) {
|
|
|
585
607
|
else if (positionals[0] === 'room-models' && input) result = room_models(home, input);
|
|
586
608
|
else if (positionals[0] === 'models' && input) {
|
|
587
609
|
const saved = Object.values(launch_settings(home).participants).find(profile => profile.adapter === input.adapter);
|
|
588
|
-
result = await
|
|
610
|
+
result = await cached_software_models(home, { adapter: input.adapter, executable: input.executable || saved?.executable }, { refresh: input.refresh === true });
|
|
589
611
|
}
|
|
590
612
|
else if (positionals[0] === 'room-member' && input) result = await room_member(home, input);
|
|
591
613
|
else if (positionals[0] === 'start' && input) result = await launch_discussion(home, input, { dry_run: values['dry-run'], browser_request: values.browser });
|
package/web/app.js
CHANGED
|
@@ -1591,7 +1591,7 @@ async function load_launch_models(name, force = false) {
|
|
|
1591
1591
|
const catalogs = state.launch.model_catalogs ||= {}, key = model_catalog_key(profile);
|
|
1592
1592
|
if (catalogs[key]?.loading || (!force && catalogs[key])) return;
|
|
1593
1593
|
const current = { models: [], loading: true, error: "", source: "" };
|
|
1594
|
-
const input = { adapter: profile.adapter, ...(profile.executable ? { executable: profile.executable } : {}) };
|
|
1594
|
+
const input = { adapter: profile.adapter, ...(profile.executable ? { executable: profile.executable } : {}), ...(force ? { refresh: true } : {}) };
|
|
1595
1595
|
catalogs[key] = current;
|
|
1596
1596
|
publish_view();
|
|
1597
1597
|
try {
|