@triflux/remote 10.38.0 → 10.39.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@triflux/remote",
3
- "version": "10.38.0",
3
+ "version": "10.39.0",
4
4
  "description": "triflux remote — team mode, psmux, MCP workers, SQLite store.",
5
5
  "type": "module",
6
6
  "main": "hub/index.mjs",
@@ -8,23 +8,49 @@ import {
8
8
  import { homedir } from "node:os";
9
9
  import { join } from "node:path";
10
10
 
11
+ // 모델명 SSOT. 값은 agy 1.0.x `agy models` 가 출력하는 display name 형식이다
12
+ // (`--model` 인자가 이 문자열을 받는다). 옛 `gemini-*-preview` ID 형식이 아님.
11
13
  const DEFAULT_GEMINI_PROFILES = {
12
- model: "gemini-3.1-pro-preview",
14
+ model: "Gemini 3.5 Flash (Medium)",
13
15
  profiles: {
16
+ flash35_low: {
17
+ model: "Gemini 3.5 Flash (Low)",
18
+ hint: "3.5 Flash (Low) — 경량·저비용",
19
+ },
20
+ flash35: {
21
+ model: "Gemini 3.5 Flash (Medium)",
22
+ hint: "3.5 Flash (Medium) — 기본, 비용·속도 균형",
23
+ },
24
+ flash35_high: {
25
+ model: "Gemini 3.5 Flash (High)",
26
+ hint: "3.5 Flash (High) — 코드/추론 강화",
27
+ },
28
+ pro31_low: {
29
+ model: "Gemini 3.1 Pro (Low)",
30
+ hint: "3.1 Pro (Low) — 플래그십 경량",
31
+ },
14
32
  pro31: {
15
- model: "gemini-3.1-pro-preview",
16
- hint: "3.1 Pro — 플래그십 (1M ctx, 멀티모달)",
33
+ model: "Gemini 3.1 Pro (High)",
34
+ hint: "3.1 Pro (High) — 플래그십 최고 ( 컨텍스트/복잡 추론)",
17
35
  },
18
36
  flash3: {
19
- model: "gemini-3-flash-preview",
20
- hint: "3.0 Flash — 빠른 응답, 비용 효율",
37
+ model: "Gemini 3 Flash",
38
+ hint: "3.0 Flash — 레거시 호환",
21
39
  },
22
- pro25: { model: "gemini-2.5-pro", hint: "2.5 Pro — 안정 (추론 강화)" },
23
- flash25: { model: "gemini-2.5-flash", hint: "2.5 Flash — 경량 범용" },
24
- lite25: { model: "gemini-2.5-flash-lite", hint: "2.5 Flash Lite — 최경량" },
25
40
  },
26
41
  };
27
42
 
43
+ // 1회 마이그레이션 테이블: 옛 ID 형식 모델값 → agy display name.
44
+ // null = deprecated(2.5 계열) → 해당 프로필 제거 대상.
45
+ const LEGACY_MODEL_MIGRATION = {
46
+ "gemini-3.1-pro-preview": "Gemini 3.1 Pro (High)",
47
+ "gemini-3-flash-preview": "Gemini 3 Flash",
48
+ "gemini-2.5-pro": null,
49
+ "gemini-2.5-flash": null,
50
+ "gemini-2.5-flash-lite": null,
51
+ };
52
+ const LEGACY_PROFILE_NAMES = ["pro25", "flash25", "lite25"];
53
+
28
54
  const DEFAULT_PROFILE_COUNT = Object.keys(
29
55
  DEFAULT_GEMINI_PROFILES.profiles,
30
56
  ).length;
@@ -80,6 +106,39 @@ function ensureGeminiProfiles({
80
106
  )
81
107
  cfg.profiles = {};
82
108
 
109
+ // ── 1회 마이그레이션: deprecated 2.5 프로필 prune + 옛 ID 형식 → display name ──
110
+ // merge-only 로직만으로는 기존 사용자 파일에 남은 stale 프로필/옛 모델 ID 가
111
+ // 정리되지 않으므로, 신규 default 를 채우기 전에 마이그레이션을 먼저 적용한다.
112
+ let migrated = false;
113
+ for (const legacy of LEGACY_PROFILE_NAMES) {
114
+ if (cfg.profiles[legacy]) {
115
+ delete cfg.profiles[legacy];
116
+ migrated = true;
117
+ }
118
+ }
119
+ for (const [pname, pval] of Object.entries(cfg.profiles)) {
120
+ const mid = typeof pval === "string" ? pval : pval?.model;
121
+ if (mid && Object.hasOwn(LEGACY_MODEL_MIGRATION, mid)) {
122
+ const repl = LEGACY_MODEL_MIGRATION[mid];
123
+ if (repl === null) {
124
+ delete cfg.profiles[pname];
125
+ } else if (typeof pval === "string") {
126
+ cfg.profiles[pname] = repl;
127
+ } else {
128
+ cfg.profiles[pname].model = repl;
129
+ }
130
+ migrated = true;
131
+ }
132
+ }
133
+ if (
134
+ typeof cfg.model === "string" &&
135
+ Object.hasOwn(LEGACY_MODEL_MIGRATION, cfg.model)
136
+ ) {
137
+ // 옛 ID 형식 기본값은 구버전 자동 생성값이므로 새 기본(DEFAULT)으로 정규화한다.
138
+ cfg.model = DEFAULT_GEMINI_PROFILES.model;
139
+ migrated = true;
140
+ }
141
+
83
142
  let added = 0;
84
143
  for (const [name, value] of Object.entries(
85
144
  DEFAULT_GEMINI_PROFILES.profiles,
@@ -91,7 +150,12 @@ function ensureGeminiProfiles({
91
150
  }
92
151
  if (!cfg.model) cfg.model = DEFAULT_GEMINI_PROFILES.model;
93
152
 
94
- if (added > 0) {
153
+ if (added > 0 || migrated) {
154
+ if (migrated) {
155
+ try {
156
+ copyFileSync(profilesPath, profilesPath + `.bak.${Date.now()}`);
157
+ } catch {}
158
+ }
95
159
  writeFileSync(profilesPath, JSON.stringify(cfg, null, 2) + "\n", {
96
160
  encoding: "utf8",
97
161
  mode: 0o600,