ai-lab-bridge 0.1.5 → 0.1.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 (2) hide show
  1. package/index.js +24 -3
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -270,8 +270,22 @@ class Session {
270
270
  /** 归一化后缓存 + 回传 usage:各家 CLI 字段名不同(input_tokens/input/prompt_tokens...),统一为平台口径 */
271
271
  emitUsage(usage) {
272
272
  const num = (v) => (typeof v === "number" && isFinite(v) ? v : undefined);
273
- const raw = usage && typeof usage === "object" ? usage : null;
273
+ let raw = usage && typeof usage === "object" ? usage : null;
274
274
  if (!raw) return;
275
+ // gemini 家族(qwen/iflow 同源)stats 为嵌套结构:
276
+ // {models: {"<模型名>": {tokens: {prompt, candidates, total, cached, thoughts}}}}
277
+ if (raw.models && typeof raw.models === "object") {
278
+ const first = Object.values(raw.models).find((m) => m && m.tokens && typeof m.tokens === "object");
279
+ const tk = first && first.tokens;
280
+ if (tk) {
281
+ raw = {
282
+ ...raw,
283
+ input: num(tk.prompt) ?? num(raw.input),
284
+ output: num(tk.candidates) ?? num(raw.output),
285
+ cache: { read: num(tk.cached) },
286
+ };
287
+ }
288
+ }
275
289
  // opencode 系: {input, output, cache:{read}} / claude: {input_tokens, output_tokens, cache_read_input_tokens}
276
290
  // codex: {input_tokens, output_tokens, total_tokens} / gemini: {inputTokenCount, outputTokenCount, ...}
277
291
  const input = num(raw.input_tokens) ?? num(raw.input) ?? num(raw.prompt_tokens) ?? num(raw.inputTokenCount);
@@ -778,6 +792,13 @@ function startSession(message) {
778
792
  if (sessionRef) argv[1].push("--resume", sessionRef);
779
793
  if (options.permission_mode) argv[1].push("--permission-mode", String(options.permission_mode));
780
794
  if (options.model) argv[1].push("--model", String(options.model));
795
+ } else if (cli === "qwen") {
796
+ // qwen 0.24+ 与 claude 同源(实测 0.24.6 stream-json 格式兼容),启动参数使用 qwen 自己的
797
+ // --approval-mode(5 档:plan/default/auto-edit/auto/yolo),不复用 claude 的 --permission-mode
798
+ argv = [cli, ["-p", "--output-format", "stream-json", "--verbose"]];
799
+ if (sessionRef) argv[1].push("--resume", sessionRef);
800
+ if (options.permission_mode) argv[1].push("--approval-mode", String(options.permission_mode));
801
+ if (options.model) argv[1].push("--model", String(options.model));
781
802
  } else if (cli === "codex") {
782
803
  argv = ["codex", ["exec", "--json", "-"]];
783
804
  if (sessionRef) argv = ["codex", ["exec", "resume", sessionRef, "--json", "-"]];
@@ -845,10 +866,10 @@ function startSession(message) {
845
866
  session.child = child;
846
867
 
847
868
  const opencodeLike = cli === "opencode" || cli === "codefree-o";
848
- const handler = cli === "claude" ? handleClaudeLine
869
+ const handler = (cli === "claude" || cli === "qwen") ? handleClaudeLine
849
870
  : cli === "codex" ? handleCodexLine
850
871
  : cli === "cursor" ? handleCursorLine
851
- : (cli === "gemini" || cli === "qwen" || cli === "iflow") ? handleGeminiLine
872
+ : (cli === "gemini" || cli === "iflow") ? handleGeminiLine
852
873
  : (session, obj, rawLine) => {
853
874
  // OpenCode / codefree-o:JSON 事件宽松解析;非 JSON 行按纯文本兜底(不支持 --format json 的版本)。
854
875
  if (obj) handleOpencodeLine(session, obj);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-lab-bridge",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "AI 开发平台设备桥接进程:反连平台 WebSocket,驱动本地 Claude Code / Codex CLI 执行任务并回传事件流",
5
5
  "license": "MIT",
6
6
  "files": [