@damn-dev/cli 0.9.12 → 0.9.13

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": "@damn-dev/cli",
3
- "version": "0.9.12",
3
+ "version": "0.9.13",
4
4
  "description": "damn.dev — self-hosted workspace OS for human + AI agent collaboration.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://damn.dev",
@@ -15857,19 +15857,29 @@ var require_agents = __commonJS({
15857
15857
  var DOCKER_COMPOSE_LOCAL_PATH = (0, path_12.join)(DAMN_DEV_DIR, "docker-compose.local.yml");
15858
15858
  var reloadDebounceTimers = /* @__PURE__ */ new Map();
15859
15859
  exports2.WELL_KNOWN_MODELS = [
15860
- "qwen3:14b",
15861
- "qwen3:32b",
15862
- "tomng/nanbeige4.1",
15860
+ // OpenRouter Free
15863
15861
  "meta-llama/llama-3.3-70b-instruct:free",
15864
15862
  "google/gemma-3-27b-it:free",
15865
15863
  "mistralai/mistral-7b-instruct:free",
15864
+ // OpenRouter Paid
15865
+ "openrouter/anthropic/claude-haiku-4.5",
15866
+ "openrouter/anthropic/claude-sonnet-4.6",
15867
+ "openrouter/anthropic/claude-opus-4.7",
15868
+ "openrouter/openai/gpt-5.4-mini",
15869
+ "openrouter/openai/gpt-5.4",
15870
+ "openrouter/google/gemini-2.5-flash",
15871
+ "openrouter/google/gemini-2.5-pro",
15872
+ // Anthropic direct
15866
15873
  "anthropic/claude-haiku-4.5",
15867
15874
  "anthropic/claude-sonnet-4.6",
15868
- "anthropic/claude-opus-4.6",
15869
- "openai/gpt-4o-mini",
15870
- "openai/gpt-4o",
15871
- "google/gemini-2.5-pro",
15872
- "google/gemini-2.5-flash"
15875
+ "anthropic/claude-opus-4.7",
15876
+ // OpenAI direct
15877
+ "openai/gpt-5.4-nano",
15878
+ "openai/gpt-5.4-mini",
15879
+ "openai/gpt-5.4",
15880
+ // Google direct
15881
+ "google/gemini-2.5-flash",
15882
+ "google/gemini-2.5-pro"
15873
15883
  ];
15874
15884
  function agentDir(slug) {
15875
15885
  return (0, path_12.join)(openclaw_12.OPENCLAW_DIR, "agents", slug);
@@ -18055,6 +18065,7 @@ var require_onboarding = __commonJS({
18055
18065
  };
18056
18066
  Object.defineProperty(exports2, "__esModule", { value: true });
18057
18067
  exports2.onboardingRouter = void 0;
18068
+ exports2.invalidateProviderModelsCache = invalidateProviderModelsCache;
18058
18069
  exports2.ensureDamndevChannel = ensureDamndevChannel;
18059
18070
  var trpc_12 = require_trpc();
18060
18071
  var db_12 = require_db();
@@ -18084,6 +18095,87 @@ var require_onboarding = __commonJS({
18084
18095
  function reloadCoo() {
18085
18096
  (0, triggerAgent_12.bumpSessionVersion)("coo");
18086
18097
  }
18098
+ var PROVIDER_MODELS_TTL_MS = 5 * 60 * 1e3;
18099
+ var providerModelsCache = null;
18100
+ function invalidateProviderModelsCache() {
18101
+ providerModelsCache = null;
18102
+ }
18103
+ async function fetchOpenRouterModels() {
18104
+ try {
18105
+ const rows = await db_12.db.availableModel.findMany({ select: { id: true, name: true } });
18106
+ return rows.map((r) => ({ id: `openrouter/${r.id}`, label: r.name || r.id }));
18107
+ } catch {
18108
+ return [];
18109
+ }
18110
+ }
18111
+ async function fetchAnthropicModels(key) {
18112
+ try {
18113
+ const res = await fetch(`${ANTHROPIC_URL}/models`, {
18114
+ headers: { "x-api-key": key, "anthropic-version": "2023-06-01" },
18115
+ signal: AbortSignal.timeout(5e3)
18116
+ });
18117
+ if (!res.ok)
18118
+ return [];
18119
+ const body = await res.json();
18120
+ return (body.data ?? []).map((m) => ({ id: `anthropic/${m.id}`, label: m.display_name ?? m.id }));
18121
+ } catch {
18122
+ return [];
18123
+ }
18124
+ }
18125
+ async function fetchOpenAIModels(key) {
18126
+ try {
18127
+ const res = await fetch("https://api.openai.com/v1/models", {
18128
+ headers: { Authorization: `Bearer ${key}` },
18129
+ signal: AbortSignal.timeout(5e3)
18130
+ });
18131
+ if (!res.ok)
18132
+ return [];
18133
+ const body = await res.json();
18134
+ return (body.data ?? []).map((m) => ({ id: `openai/${m.id}`, label: m.id }));
18135
+ } catch {
18136
+ return [];
18137
+ }
18138
+ }
18139
+ async function fetchGoogleModels(key) {
18140
+ try {
18141
+ const res = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${encodeURIComponent(key)}`, {
18142
+ signal: AbortSignal.timeout(5e3)
18143
+ });
18144
+ if (!res.ok)
18145
+ return [];
18146
+ const body = await res.json();
18147
+ return (body.models ?? []).filter((m) => !m.supportedGenerationMethods || m.supportedGenerationMethods.includes("generateContent")).map((m) => {
18148
+ const id = (m.name ?? "").replace(/^models\//, "");
18149
+ return { id: `google/${id}`, label: m.displayName ?? id };
18150
+ }).filter((m) => m.id !== "google/");
18151
+ } catch {
18152
+ return [];
18153
+ }
18154
+ }
18155
+ async function getProviderModelsCached() {
18156
+ if (providerModelsCache && Date.now() - providerModelsCache.ts < PROVIDER_MODELS_TTL_MS) {
18157
+ return providerModelsCache.data;
18158
+ }
18159
+ let providers = {};
18160
+ try {
18161
+ const config = await (0, openclaw_12.readOpenClawConfig)();
18162
+ providers = config?.models?.providers ?? {};
18163
+ } catch {
18164
+ }
18165
+ const openrouterKey = providers.openrouter?.apiKey;
18166
+ const anthropicKey = providers.anthropic?.apiKey;
18167
+ const openaiKey = providers.openai?.apiKey;
18168
+ const googleKey = providers.google?.apiKey;
18169
+ const [openrouter, anthropic, openai, google] = await Promise.all([
18170
+ typeof openrouterKey === "string" && openrouterKey.length > 0 ? fetchOpenRouterModels() : Promise.resolve([]),
18171
+ typeof anthropicKey === "string" && anthropicKey.length > 0 ? fetchAnthropicModels(anthropicKey) : Promise.resolve([]),
18172
+ typeof openaiKey === "string" && openaiKey.length > 0 ? fetchOpenAIModels(openaiKey) : Promise.resolve([]),
18173
+ typeof googleKey === "string" && googleKey.length > 0 ? fetchGoogleModels(googleKey) : Promise.resolve([])
18174
+ ]);
18175
+ const data = { openrouter, anthropic, openai, google };
18176
+ providerModelsCache = { ts: Date.now(), data };
18177
+ return data;
18178
+ }
18087
18179
  async function getOrCreateState() {
18088
18180
  return db_12.db.onboardingState.upsert({
18089
18181
  where: { id: "singleton" },
@@ -18613,14 +18705,16 @@ Or just tell me what you're working on \u2014 I'll figure out the rest.`
18613
18705
  return path_12.default.join((0, os_12.homedir)(), "openclaw-plugins", "damndev");
18614
18706
  }
18615
18707
  var PRIMARY_MODEL_PRIORITY = [
18708
+ "anthropic/claude-opus-4.7",
18616
18709
  "anthropic/claude-opus-4.6",
18617
18710
  "anthropic/claude-sonnet-4.6",
18618
- "anthropic/claude-sonnet-4.5",
18711
+ "openai/gpt-5.4",
18619
18712
  "openai/gpt-4o"
18620
18713
  ];
18621
18714
  var SECONDARY_MODEL_PRIORITY = [
18622
- "anthropic/claude-sonnet-4.6",
18623
- "google/gemini-2.5-pro",
18715
+ "anthropic/claude-haiku-4.5",
18716
+ "openai/gpt-5.4-mini",
18717
+ "google/gemini-2.5-flash",
18624
18718
  "openai/gpt-4o-mini"
18625
18719
  ];
18626
18720
  function pickDefaultModels(models) {
@@ -18880,6 +18974,7 @@ Or just tell me what you're working on \u2014 I'll figure out the rest.`
18880
18974
  models: []
18881
18975
  };
18882
18976
  await (0, openclaw_12.writeOpenClawConfig)(ocConfig);
18977
+ invalidateProviderModelsCache();
18883
18978
  } catch {
18884
18979
  }
18885
18980
  return { valid: true, modelCount: models.length, suggestedReasoningModel, suggestedFastModel };
@@ -18906,7 +19001,7 @@ Or just tell me what you're working on \u2014 I'll figure out the rest.`
18906
19001
  const valid = res.status !== 401 && res.status !== 403;
18907
19002
  if (!valid)
18908
19003
  return { valid: false, modelCount: 0, suggestedReasoningModel: null, suggestedFastModel: null };
18909
- const suggestedReasoningModel = "anthropic/claude-sonnet-4.6";
19004
+ const suggestedReasoningModel = "anthropic/claude-opus-4.7";
18910
19005
  const suggestedFastModel = "anthropic/claude-haiku-4.5";
18911
19006
  try {
18912
19007
  const ocConfig = await (0, openclaw_12.readOpenClawConfig)();
@@ -18922,9 +19017,10 @@ Or just tell me what you're working on \u2014 I'll figure out the rest.`
18922
19017
  ocConfig.agents.defaults = {};
18923
19018
  if (!ocConfig.agents.defaults.model)
18924
19019
  ocConfig.agents.defaults.model = {};
18925
- ocConfig.agents.defaults.model.primary = "anthropic/claude-sonnet-4.6";
19020
+ ocConfig.agents.defaults.model.primary = "anthropic/claude-opus-4.7";
18926
19021
  }
18927
19022
  await (0, openclaw_12.writeOpenClawConfig)(ocConfig);
19023
+ invalidateProviderModelsCache();
18928
19024
  } catch {
18929
19025
  }
18930
19026
  return { valid: true, modelCount: 0, suggestedReasoningModel, suggestedFastModel };
@@ -18940,8 +19036,8 @@ Or just tell me what you're working on \u2014 I'll figure out the rest.`
18940
19036
  });
18941
19037
  if (!res.ok)
18942
19038
  return { valid: false, modelCount: 0, suggestedReasoningModel: null, suggestedFastModel: null };
18943
- const suggestedReasoningModel = "openai/gpt-4o";
18944
- const suggestedFastModel = "openai/gpt-4o-mini";
19039
+ const suggestedReasoningModel = "openai/gpt-5.4";
19040
+ const suggestedFastModel = "openai/gpt-5.4-mini";
18945
19041
  try {
18946
19042
  const ocConfig = await (0, openclaw_12.readOpenClawConfig)();
18947
19043
  if (!ocConfig.models)
@@ -18956,9 +19052,10 @@ Or just tell me what you're working on \u2014 I'll figure out the rest.`
18956
19052
  ocConfig.agents.defaults = {};
18957
19053
  if (!ocConfig.agents.defaults.model)
18958
19054
  ocConfig.agents.defaults.model = {};
18959
- ocConfig.agents.defaults.model.primary = "openai/gpt-4o";
19055
+ ocConfig.agents.defaults.model.primary = "openai/gpt-5.4";
18960
19056
  }
18961
19057
  await (0, openclaw_12.writeOpenClawConfig)(ocConfig);
19058
+ invalidateProviderModelsCache();
18962
19059
  } catch {
18963
19060
  }
18964
19061
  return { valid: true, modelCount: 0, suggestedReasoningModel, suggestedFastModel };
@@ -18990,6 +19087,7 @@ Or just tell me what you're working on \u2014 I'll figure out the rest.`
18990
19087
  ocConfig.agents.defaults.model.primary = "google/gemini-2.5-flash";
18991
19088
  }
18992
19089
  await (0, openclaw_12.writeOpenClawConfig)(ocConfig);
19090
+ invalidateProviderModelsCache();
18993
19091
  } catch {
18994
19092
  }
18995
19093
  return { valid: true, modelCount: 0, suggestedReasoningModel, suggestedFastModel };
@@ -19098,14 +19196,49 @@ Or just tell me what you're working on \u2014 I'll figure out the rest.`
19098
19196
  return { enabled: !!(process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_ID.length > 0) };
19099
19197
  }),
19100
19198
  providersConfigured: trpc_12.protectedProcedure.query(async () => {
19101
- let openrouter = false;
19199
+ const result = { openrouter: false, anthropic: false, openai: false, google: false };
19102
19200
  try {
19103
19201
  const config = await (0, openclaw_12.readOpenClawConfig)();
19104
- const key = config?.models?.providers?.openrouter?.apiKey;
19105
- openrouter = typeof key === "string" && key.length > 0;
19202
+ const providers = config?.models?.providers ?? {};
19203
+ for (const key of ["openrouter", "anthropic", "openai", "google"]) {
19204
+ const apiKey = providers[key]?.apiKey;
19205
+ result[key] = typeof apiKey === "string" && apiKey.length > 0;
19206
+ }
19106
19207
  } catch {
19107
19208
  }
19108
- return { openrouter };
19209
+ return result;
19210
+ }),
19211
+ removeProviderKey: trpc_12.protectedProcedure.input(zod_12.z.object({ provider: zod_12.z.enum(["openrouter", "anthropic", "openai", "google"]) })).mutation(async ({ input }) => {
19212
+ const config = await (0, openclaw_12.readOpenClawConfig)();
19213
+ if (config?.models?.providers?.[input.provider]) {
19214
+ delete config.models.providers[input.provider];
19215
+ }
19216
+ const prefix = `${input.provider}/`;
19217
+ const defaults = config?.agents?.defaults?.model;
19218
+ if (defaults) {
19219
+ if (typeof defaults.primary === "string" && defaults.primary.startsWith(prefix)) {
19220
+ delete defaults.primary;
19221
+ }
19222
+ if (Array.isArray(defaults.fallbacks)) {
19223
+ defaults.fallbacks = defaults.fallbacks.filter((m) => typeof m !== "string" || !m.startsWith(prefix));
19224
+ }
19225
+ }
19226
+ const list = config?.agents?.list ?? [];
19227
+ for (const agent of list) {
19228
+ const m = agent?.model;
19229
+ if (m && typeof m.primary === "string" && m.primary.startsWith(prefix)) {
19230
+ delete m.primary;
19231
+ }
19232
+ if (m && Array.isArray(m.fallbacks)) {
19233
+ m.fallbacks = m.fallbacks.filter((x) => typeof x !== "string" || !x.startsWith(prefix));
19234
+ }
19235
+ }
19236
+ await (0, openclaw_12.writeOpenClawConfig)(config);
19237
+ invalidateProviderModelsCache();
19238
+ return { ok: true };
19239
+ }),
19240
+ discoverProviderModels: trpc_12.protectedProcedure.query(async () => {
19241
+ return await getProviderModelsCached();
19109
19242
  }),
19110
19243
  signupAllowed: trpc_12.publicProcedure.query(async () => {
19111
19244
  const accountCount = await db_12.db.account.count();
@@ -28031,7 +28164,7 @@ var require_package = __commonJS({
28031
28164
  module2.exports = {
28032
28165
  name: "backend",
28033
28166
  private: true,
28034
- version: "0.9.12",
28167
+ version: "0.9.13",
28035
28168
  scripts: {
28036
28169
  dev: "tsx watch src/server.ts",
28037
28170
  build: "tsc && cp -r resources dist/resources",