@wrongstack/core 0.292.0 → 0.293.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.
Files changed (65) hide show
  1. package/dist/coordination/index.d.ts +1 -1
  2. package/dist/coordination/index.d.ts.map +1 -1
  3. package/dist/coordination/index.js +163 -39
  4. package/dist/coordination/index.js.map +3 -3
  5. package/dist/coordination/mailbox-http-router.d.ts +38 -0
  6. package/dist/coordination/mailbox-http-router.d.ts.map +1 -1
  7. package/dist/coordination/provider-status-tracker.d.ts.map +1 -1
  8. package/dist/core/fallback-model.d.ts.map +1 -1
  9. package/dist/core/fallback-profile-manager.d.ts +0 -2
  10. package/dist/core/fallback-profile-manager.d.ts.map +1 -1
  11. package/dist/core/system-prompt-builder.d.ts.map +1 -1
  12. package/dist/defaults/index.js +351 -318
  13. package/dist/defaults/index.js.map +4 -4
  14. package/dist/execution/compaction-core.d.ts +3 -0
  15. package/dist/execution/compaction-core.d.ts.map +1 -1
  16. package/dist/execution/compactor.d.ts +4 -0
  17. package/dist/execution/compactor.d.ts.map +1 -1
  18. package/dist/execution/index.js +141 -50
  19. package/dist/execution/index.js.map +4 -4
  20. package/dist/execution/intelligent-compactor.d.ts +5 -1
  21. package/dist/execution/intelligent-compactor.d.ts.map +1 -1
  22. package/dist/execution/one-shot-llm.d.ts.map +1 -1
  23. package/dist/execution/selective-compactor.d.ts +4 -0
  24. package/dist/execution/selective-compactor.d.ts.map +1 -1
  25. package/dist/goal/phase-orchestrator.d.ts +4 -0
  26. package/dist/goal/phase-orchestrator.d.ts.map +1 -1
  27. package/dist/hooks/runner.d.ts +0 -2
  28. package/dist/hooks/runner.d.ts.map +1 -1
  29. package/dist/index.d.ts +1 -1
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +421 -248
  32. package/dist/index.js.map +4 -4
  33. package/dist/models/alibaba-token-plan-catalog.d.ts +85 -0
  34. package/dist/models/alibaba-token-plan-catalog.d.ts.map +1 -0
  35. package/dist/models/index.d.ts +1 -0
  36. package/dist/models/index.d.ts.map +1 -1
  37. package/dist/models/index.js +200 -15
  38. package/dist/models/index.js.map +4 -4
  39. package/dist/models/llm-selector.d.ts +4 -0
  40. package/dist/models/llm-selector.d.ts.map +1 -1
  41. package/dist/models/models-registry.d.ts +8 -0
  42. package/dist/models/models-registry.d.ts.map +1 -1
  43. package/dist/security/index.js +0 -23
  44. package/dist/security/index.js.map +2 -2
  45. package/dist/security/permission-policy.d.ts +0 -23
  46. package/dist/security/permission-policy.d.ts.map +1 -1
  47. package/dist/storage/config-loader.d.ts.map +1 -1
  48. package/dist/storage/index.js +6 -5
  49. package/dist/storage/index.js.map +2 -2
  50. package/dist/tools/index.js +8 -1
  51. package/dist/tools/index.js.map +2 -2
  52. package/dist/types/config.d.ts +9 -16
  53. package/dist/types/config.d.ts.map +1 -1
  54. package/dist/types/index.js +7 -4
  55. package/dist/types/index.js.map +2 -2
  56. package/dist/types/provider.d.ts.map +1 -1
  57. package/dist/utils/connectivity.d.ts +36 -0
  58. package/dist/utils/connectivity.d.ts.map +1 -0
  59. package/dist/utils/index.d.ts +1 -0
  60. package/dist/utils/index.d.ts.map +1 -1
  61. package/dist/utils/index.js +59 -11
  62. package/dist/utils/index.js.map +4 -4
  63. package/dist/utils/merge-models-payload.d.ts +9 -0
  64. package/dist/utils/merge-models-payload.d.ts.map +1 -1
  65. package/package.json +2 -2
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Offline **floor** for the Alibaba Cloud Model Studio Token Plan (Personal
3
+ * Edition) models, sourced from the official documentation at:
4
+ * https://www.alibabacloud.com/help/en/model-studio/token-plan-personal-overview
5
+ *
6
+ * Source-of-truth precedence (live path wins):
7
+ * 1. The curated overlay `packages/cli/data/providers.json` — provider
8
+ * `alibaba-token-plan` — synced from the official doc + cached + bundled
9
+ * offline by `DefaultModelsRegistry` (overlayUrl/overlayFile). Editing
10
+ * that JSON and pushing updates every client without a code release;
11
+ * this is the authoritative list whenever the registry overlay is wired
12
+ * (the CLI path).
13
+ * 2. This hardcoded table — the last-resort floor used where no overlay is
14
+ * available (a standalone registry without the bundled file) and by the
15
+ * CLI auth-menu login flow, which needs a synchronous id list.
16
+ *
17
+ * Keep this in lockstep with the `alibaba-token-plan` block in
18
+ * `providers.json`; the drift-guard test
19
+ * `packages/cli/tests/alibaba-token-plan-catalog-overlay-sync.test.ts`
20
+ * asserts they agree.
21
+ *
22
+ * ─── Correction context: models.dev vs Token Plan ─────────────────────
23
+ * The models.dev catalog (fetched by DefaultModelsRegistry) reports the
24
+ * FULL Alibaba Cloud Model Studio model inventory — hundreds of models
25
+ * across pay-per-use, legacy snapshots, Team Edition, and Personal Edition.
26
+ * The Token Plan (Personal Edition) is an exact-string allowlist that
27
+ * covers only **11 models** from 5 brands. The following models.dev
28
+ * entries are **NOT in the Personal Edition** and must NOT appear in the
29
+ * provider's model list:
30
+ *
31
+ * ❌ qwen3.6-plus Team Edition only
32
+ * ❌ deepseek-v4-flash Team Edition only
33
+ * ❌ deepseek-v3.2 Team Edition only
34
+ * ❌ qwen-image-2.0 Team Edition only (Qwen image gen)
35
+ * ❌ qwen-image-2.0-pro Team Edition only
36
+ * ❌ kimi-k2.7-code Team Edition only (Moonshot AI)
37
+ * ❌ kimi-k2.6 Team Edition only
38
+ * ❌ kimi-k2.5 Team Edition only
39
+ * ❌ glm-5.1 Team Edition only
40
+ * ❌ glm-5 Team Edition only
41
+ * ❌ MiniMax-M2.5 Team Edition only
42
+ * ❌ qwen3-max Legacy pay-per-use (not in any Token Plan)
43
+ * ❌ qwen3.5-plus / flash Legacy pay-per-use
44
+ * ❌ qwen3-coder-plus Legacy pay-per-use
45
+ * ❌ qwen-long 10M-token model, not in Token Plan
46
+ * ❌ qwen3-math-plus Specialised model, not in Token Plan
47
+ * ❌ qwen3-235b-a22b Open-weight, pay-per-use
48
+ * ❌ wan2.7-t2v-turbo Different Wanx variant, verify availability
49
+ *
50
+ * See packages/cli/data/providers.json for the authoritative model
51
+ * allowlist.
52
+ * ──────────────────────────────────────────────────────────────────────
53
+ */
54
+ export interface AlibabaTokenPlanModelMeta {
55
+ /** The wire id sent to the backend (e.g. `qwen3.7-max`). */
56
+ id: string;
57
+ /** Human-readable display name shown in pickers. */
58
+ name: string;
59
+ /** One-line capability blurb. */
60
+ description: string;
61
+ /** Capability tags — which modality/feature this model supports. */
62
+ capabilities: string[];
63
+ /** Context window in tokens (where applicable). */
64
+ contextWindow?: number;
65
+ /** Max output tokens (where documented). */
66
+ maxOutput?: number;
67
+ /** The recommended / latest model — tagged "(current)" in the official UI. */
68
+ current?: boolean;
69
+ /** Explicit input modality declaration (e.g. image-conditioned video models). */
70
+ inputs?: ReadonlyArray<'text' | 'image'>;
71
+ }
72
+ /**
73
+ * Token Plan Personal Edition models, newest-first. The first entry is the
74
+ * recommended default (`current`). Order is significant: callers that need a
75
+ * default model id use `ALIBABA_TOKEN_PLAN_MODELS[0]`.
76
+ *
77
+ * Corresponds to the "Supported models" table on:
78
+ * https://www.alibabacloud.com/help/en/model-studio/token-plan-personal-overview
79
+ *
80
+ * Last verified: 2026-07-20 (official doc last updated Jul 19, 2026)
81
+ */
82
+ export declare const ALIBABA_TOKEN_PLAN_MODELS: ReadonlyArray<AlibabaTokenPlanModelMeta>;
83
+ /** Look up the canonical metadata for a Token Plan model id, or `undefined`. */
84
+ export declare function alibabaTokenPlanModelMeta(id: string): AlibabaTokenPlanModelMeta | undefined;
85
+ //# sourceMappingURL=alibaba-token-plan-catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alibaba-token-plan-catalog.d.ts","sourceRoot":"","sources":["../../src/models/alibaba-token-plan-catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAEH,MAAM,WAAW,yBAAyB;IACxC,4DAA4D;IAC5D,EAAE,EAAE,MAAM,CAAC;IACX,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mDAAmD;IACnD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iFAAiF;IACjF,MAAM,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,OAAO,CAAC,CAAC;CAC1C;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,yBAAyB,CAiG9E,CAAC;AAMF,gFAAgF;AAChF,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,MAAM,GACT,yBAAyB,GAAG,SAAS,CAEvC"}
@@ -3,6 +3,7 @@ export { DefaultModeStore, loadProjectModes, loadUserModes, type ModeLoaderOptio
3
3
  export { LLMSelector, type LLMSelectorOptions } from './llm-selector.js';
4
4
  export { resolveProviderModelList, describeCatalogModel, type ProviderModelDescriptor, } from './provider-model-resolve.js';
5
5
  export { CODEX_MODELS, codexModelMeta, type CodexModelMeta } from './codex-catalog.js';
6
+ export { ALIBABA_TOKEN_PLAN_MODELS, alibabaTokenPlanModelMeta, type AlibabaTokenPlanModelMeta, } from './alibaba-token-plan-catalog.js';
6
7
  export { MODEL_PROFILES, TASK_TO_ROLE, inferTaskType, findModelProfile, scoreModelForTask, type ModelProfile, type TaskType, } from './model-intelligence.js';
7
8
  export { ModelRouter, type RouterConfig, type ModelPick, type RouterCosts, type ModelIntelligenceEntry, } from './model-router.js';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,KAAK,4BAA4B,GAClC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,KAAK,uBAAuB,GAC7B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGvF,OAAO,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,QAAQ,GACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,sBAAsB,GAC5B,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/models/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,KAAK,4BAA4B,GAClC,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,KAAK,uBAAuB,GAC7B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACvF,OAAO,EACL,yBAAyB,EACzB,yBAAyB,EACzB,KAAK,yBAAyB,GAC/B,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,QAAQ,GACd,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,WAAW,EACX,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,sBAAsB,GAC5B,MAAM,mBAAmB,CAAC"}
@@ -2,6 +2,75 @@
2
2
  import * as fs2 from "node:fs/promises";
3
3
  import * as path2 from "node:path";
4
4
 
5
+ // src/utils/term.ts
6
+ var hasStdout = () => typeof process !== "undefined" && !!process.stdout;
7
+ function isStdoutTTY() {
8
+ return hasStdout() && Boolean(process.stdout.isTTY);
9
+ }
10
+ var ESCAPE_TERMINATOR = Object.freeze({
11
+ BEL: "\x07",
12
+ // OSC 0 / OSC 2 (title)
13
+ ST: "\x1B\\"
14
+ // DCS / strict OSC
15
+ });
16
+
17
+ // src/utils/color.ts
18
+ var isColorTty = () => {
19
+ if (envFlag(process.env.NO_COLOR)) return false;
20
+ if (envFlag(process.env.FORCE_COLOR)) return true;
21
+ return isStdoutTTY();
22
+ };
23
+ function envFlag(value) {
24
+ if (value === void 0) return false;
25
+ if (value.trim() === "") return false;
26
+ return !/^(0|false|no|off)$/i.test(value.trim());
27
+ }
28
+ var COLOR = isColorTty();
29
+ var wrap = (open2, close) => (s) => COLOR ? `\x1B[${open2}m${s}\x1B[${close}m` : s;
30
+ var color = {
31
+ reset: wrap("0", "0"),
32
+ bold: wrap("1", "22"),
33
+ dim: wrap("2", "22"),
34
+ italic: wrap("3", "23"),
35
+ underline: wrap("4", "24"),
36
+ red: wrap("31", "39"),
37
+ green: wrap("32", "39"),
38
+ yellow: wrap("33", "39"),
39
+ blue: wrap("34", "39"),
40
+ magenta: wrap("35", "39"),
41
+ cyan: wrap("36", "39"),
42
+ gray: wrap("90", "39"),
43
+ amber: wrap("38;5;214", "39"),
44
+ pink: wrap("38;5;205", "39"),
45
+ bgRed: wrap("41", "49"),
46
+ bgGreen: wrap("42", "49")
47
+ };
48
+
49
+ // src/infrastructure/logger.ts
50
+ var COLORS = {
51
+ error: color.red,
52
+ warn: color.yellow,
53
+ info: color.cyan,
54
+ debug: color.gray,
55
+ trace: color.dim
56
+ };
57
+ var noOpLogger = {
58
+ // 'error' is the quietest level the Logger contract offers; the methods
59
+ // discard everything regardless, this only matters to level checks.
60
+ level: "error",
61
+ error: () => {
62
+ },
63
+ warn: () => {
64
+ },
65
+ info: () => {
66
+ },
67
+ debug: () => {
68
+ },
69
+ trace: () => {
70
+ },
71
+ child: () => noOpLogger
72
+ };
73
+
5
74
  // src/utils/atomic-write.ts
6
75
  import { randomBytes } from "node:crypto";
7
76
  import * as fs from "node:fs/promises";
@@ -84,15 +153,30 @@ function estimateMessageTokens(messages) {
84
153
  }
85
154
 
86
155
  // src/utils/merge-models-payload.ts
156
+ var REMOVE_PROVIDERS_KEY = "_removeProviders";
157
+ var REMOVE_MODELS_KEY = "_removeModels";
87
158
  function mergeModelsPayload(base, overlay) {
159
+ const removeProviders = Array.isArray(overlay[REMOVE_PROVIDERS_KEY]) ? overlay[REMOVE_PROVIDERS_KEY] : [];
160
+ const removeModels = overlay[REMOVE_MODELS_KEY] && typeof overlay[REMOVE_MODELS_KEY] === "object" ? overlay[REMOVE_MODELS_KEY] : {};
88
161
  const out = {};
89
162
  for (const [id, provider] of Object.entries(base)) {
90
163
  out[id] = cloneProvider(provider);
91
164
  }
92
165
  for (const [id, ovProvider] of Object.entries(overlay)) {
166
+ if (id === REMOVE_PROVIDERS_KEY || id === REMOVE_MODELS_KEY) continue;
93
167
  const existing = out[id];
94
168
  out[id] = existing ? mergeProvider(existing, ovProvider) : cloneProvider(ovProvider);
95
169
  }
170
+ for (const providerId of removeProviders) {
171
+ delete out[providerId];
172
+ }
173
+ for (const [providerId, modelIds] of Object.entries(removeModels)) {
174
+ const provider = out[providerId];
175
+ if (!provider || !provider.models) continue;
176
+ for (const modelId of modelIds) {
177
+ delete provider.models[modelId];
178
+ }
179
+ }
96
180
  return out;
97
181
  }
98
182
  function mergeProvider(base, overlay) {
@@ -381,6 +465,7 @@ var DefaultModelsRegistry = class {
381
465
  overlayUrl;
382
466
  overlayFile;
383
467
  overlayCacheFile;
468
+ logger;
384
469
  constructor(opts) {
385
470
  this.cacheFile = opts.cacheFile;
386
471
  this.url = opts.url ?? process.env[ENV_URL_KEY] ?? DEFAULT_URL;
@@ -394,6 +479,7 @@ var DefaultModelsRegistry = class {
394
479
  this.overlayUrl = opts.overlayUrl;
395
480
  this.overlayFile = opts.overlayFile;
396
481
  this.overlayCacheFile = opts.overlayCacheFile ?? (opts.overlayUrl ? path2.join(path2.dirname(opts.cacheFile), "models-overlay-cache.json") : void 0);
482
+ this.logger = opts.logger ?? noOpLogger;
397
483
  }
398
484
  async load(opts = {}) {
399
485
  if (this.payload && !opts.force) return this.payload;
@@ -442,16 +528,18 @@ var DefaultModelsRegistry = class {
442
528
  if (cached && this.isWithinMaxStaleAge(cached.fetchedAt)) {
443
529
  this.fetchedAt = new Date(cached.fetchedAt);
444
530
  const ageSeconds = Math.floor((Date.now() - this.fetchedAt.getTime()) / 1e3);
445
- console.warn(
446
- `ModelsRegistry: models.dev unavailable (${toErrorMessage(err)}); using stale cache from ${formatAge(ageSeconds)} ago. Run \`wstack models refresh\` to retry.`
531
+ this.logger.warn(
532
+ `ModelsRegistry: models.dev unavailable (${toErrorMessage(err)}); using stale cache from ${formatAge(ageSeconds)} ago. Run \`wstack models refresh\` to retry.`,
533
+ { event: "models_registry.stale_cache_fallback" }
447
534
  );
448
535
  return cached.payload;
449
536
  }
450
537
  if (overlayAvailable) {
451
- console.warn(
538
+ this.logger.warn(
452
539
  `ModelsRegistry: models.dev unavailable (${toErrorMessage(
453
540
  err
454
- )}); serving curated overlay only.`
541
+ )}); serving curated overlay only.`,
542
+ { event: "models_registry.overlay_only_fallback" }
455
543
  );
456
544
  return {};
457
545
  }
@@ -547,8 +635,9 @@ var DefaultModelsRegistry = class {
547
635
  const cached = await this.readCacheAt(this.overlayCacheFile);
548
636
  if (cached && this.isWithinMaxStaleAge(cached.fetchedAt)) {
549
637
  const ageSeconds = Math.floor((Date.now() - new Date(cached.fetchedAt).getTime()) / 1e3);
550
- console.warn(
551
- `ModelsRegistry: overlay unavailable; using stale overlay from ${formatAge(ageSeconds)} ago.`
638
+ this.logger.warn(
639
+ `ModelsRegistry: overlay unavailable; using stale overlay from ${formatAge(ageSeconds)} ago.`,
640
+ { event: "models_registry.overlay_stale_fallback", ageSeconds }
552
641
  );
553
642
  return cached.payload;
554
643
  }
@@ -1129,11 +1218,13 @@ var LLMSelector = class {
1129
1218
  systemPrompt;
1130
1219
  maxOutputTokens;
1131
1220
  oneShotOrchestrator;
1221
+ logger;
1132
1222
  constructor(opts) {
1133
1223
  this.provider = opts.provider;
1134
1224
  this.model = opts.model ?? "unknown";
1225
+ this.logger = opts.logger ?? noOpLogger;
1135
1226
  if (this.model === "unknown" && (process.env["NODE_ENV"] === "development" || process.env["WRONGSTACK_DEBUG"] === "1")) {
1136
- console.warn(
1227
+ this.logger.warn(
1137
1228
  "[LLMSelector] model not set \u2014 selector will use the provider default. Set `model` explicitly in LLMSelectorOptions to silence this warning."
1138
1229
  );
1139
1230
  }
@@ -1183,14 +1274,9 @@ IMPORTANT: Total conversation (${totalTokens} tokens) exceeds budget (${effectiv
1183
1274
  }
1184
1275
  } catch (err) {
1185
1276
  if (err instanceof Error) {
1186
- console.warn(
1187
- JSON.stringify({
1188
- level: "warn",
1189
- event: "llm_selector.call_failed",
1190
- message: `selector call failed, using recency fallback: ${err.message}`,
1191
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
1192
- })
1193
- );
1277
+ this.logger.warn(`selector call failed, using recency fallback: ${err.message}`, {
1278
+ event: "llm_selector.call_failed"
1279
+ });
1194
1280
  }
1195
1281
  return this.fallbackSelect(messages, effectiveBudget);
1196
1282
  } finally {
@@ -1391,6 +1477,103 @@ function resolveProviderModelList(savedModels, catalog, providerHint, siblingCat
1391
1477
  return out;
1392
1478
  }
1393
1479
 
1480
+ // src/models/alibaba-token-plan-catalog.ts
1481
+ var ALIBABA_TOKEN_PLAN_MODELS = [
1482
+ // ── Qwen (flagship) ──────────────────────────────────────────────
1483
+ {
1484
+ id: "qwen3.8-max-preview",
1485
+ name: "Qwen3.8 Max Preview",
1486
+ description: "2.4T-parameter multimodal reasoning \u2014 text, image, video, documents. 10% Credits rate during preview. Night discount (22:00-08:00 UTC+8).",
1487
+ capabilities: ["reasoning", "visual-understanding", "text-generation"],
1488
+ contextWindow: 1e6,
1489
+ // speculative — matches Qwen3.7 Max; official docs pending
1490
+ maxOutput: 65536,
1491
+ current: true
1492
+ },
1493
+ {
1494
+ id: "qwen3.7-max",
1495
+ name: "Qwen3.7 Max",
1496
+ description: "Top-tier pure-text reasoning model \u2014 strongest in the Qwen3.7 series. 1M context, thinking mode, function calling.",
1497
+ capabilities: ["reasoning", "text-generation"],
1498
+ contextWindow: 1e6,
1499
+ maxOutput: 65536
1500
+ },
1501
+ {
1502
+ id: "qwen3.7-plus",
1503
+ name: "Qwen3.7 Plus",
1504
+ description: "Balanced flagship \u2014 reasoning, visual understanding, text generation. 1M context, built-in tools.",
1505
+ capabilities: ["reasoning", "visual-understanding", "text-generation"],
1506
+ contextWindow: 1e6,
1507
+ maxOutput: 65536
1508
+ },
1509
+ {
1510
+ id: "qwen3.6-flash",
1511
+ name: "Qwen3.6 Flash",
1512
+ description: "Cost-effective reasoning model \u2014 vision + text, 1M context, same context length as flagship at lower cost.",
1513
+ capabilities: ["reasoning", "visual-understanding", "text-generation"],
1514
+ contextWindow: 1e6,
1515
+ maxOutput: 65536
1516
+ },
1517
+ // ── Zhipu AI ──────────────────────────────────────────────────────
1518
+ {
1519
+ id: "glm-5.2",
1520
+ name: "GLM-5.2",
1521
+ description: "Zhipu AI flagship text-generation model \u2014 reasoning, text, 198K context, function calling, structured output.",
1522
+ capabilities: ["reasoning", "text-generation"],
1523
+ contextWindow: 198e3,
1524
+ maxOutput: 65536
1525
+ },
1526
+ // ── DeepSeek ──────────────────────────────────────────────────────
1527
+ {
1528
+ id: "deepseek-v4-pro",
1529
+ name: "DeepSeek V4 Pro",
1530
+ description: "Frontier reasoning + text generation model. 1M context, always-thinking mode.",
1531
+ capabilities: ["reasoning", "text-generation"],
1532
+ contextWindow: 1e6,
1533
+ maxOutput: 65536
1534
+ },
1535
+ // ── Wanx (image generation) ────────────────────────────────────────
1536
+ {
1537
+ id: "wan2.7-image",
1538
+ name: "Wan2.7 Image",
1539
+ description: "Text-to-image generation model by Wanx.",
1540
+ capabilities: ["image-generation"]
1541
+ },
1542
+ {
1543
+ id: "wan2.7-image-pro",
1544
+ name: "Wan2.7 Image Pro",
1545
+ description: "Higher-quality text-to-image generation model by Wanx.",
1546
+ capabilities: ["image-generation"]
1547
+ },
1548
+ // ── HappyHorse (video generation) ─────────────────────────────────
1549
+ {
1550
+ id: "happyhorse-1.1-t2v",
1551
+ name: "HappyHorse 1.1 T2V",
1552
+ description: "Text-to-video generation model by HappyHorse.",
1553
+ capabilities: ["video-generation"]
1554
+ },
1555
+ {
1556
+ id: "happyhorse-1.1-i2v",
1557
+ name: "HappyHorse 1.1 I2V",
1558
+ description: "Image-to-video generation model by HappyHorse.",
1559
+ capabilities: ["video-generation"],
1560
+ inputs: ["text", "image"]
1561
+ },
1562
+ {
1563
+ id: "happyhorse-1.1-r2v",
1564
+ name: "HappyHorse 1.1 R2V",
1565
+ description: "Reference-to-video generation model by HappyHorse.",
1566
+ capabilities: ["video-generation"],
1567
+ inputs: ["text", "image"]
1568
+ }
1569
+ ];
1570
+ var BY_ID2 = new Map(
1571
+ ALIBABA_TOKEN_PLAN_MODELS.map((m) => [m.id, m])
1572
+ );
1573
+ function alibabaTokenPlanModelMeta(id) {
1574
+ return BY_ID2.get(id);
1575
+ }
1576
+
1394
1577
  // src/models/model-intelligence.ts
1395
1578
  var MODEL_PROFILES = [
1396
1579
  // ── Anthropic ──
@@ -1882,6 +2065,7 @@ var ModelRouter = class {
1882
2065
  }
1883
2066
  };
1884
2067
  export {
2068
+ ALIBABA_TOKEN_PLAN_MODELS,
1885
2069
  CODEX_MODELS,
1886
2070
  DefaultModeStore,
1887
2071
  DefaultModelsRegistry,
@@ -1889,6 +2073,7 @@ export {
1889
2073
  MODEL_PROFILES,
1890
2074
  ModelRouter,
1891
2075
  TASK_TO_ROLE,
2076
+ alibabaTokenPlanModelMeta,
1892
2077
  classifyFamily,
1893
2078
  codexModelMeta,
1894
2079
  describeCatalogModel,