cascade-ai 0.3.0 → 0.4.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/dist/cli.cjs CHANGED
@@ -130,7 +130,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
130
130
  var CASCADE_VERSION, CASCADE_CONFIG_FILE, CASCADE_DB_FILE, CASCADE_DASHBOARD_SECRET_FILE, GLOBAL_CONFIG_DIR, GLOBAL_DB_FILE, GLOBAL_KEYSTORE_FILE, GLOBAL_RUNTIME_DB_FILE, DEFAULT_DASHBOARD_PORT, DEFAULT_CONTEXT_LIMIT, DEFAULT_AUTO_SUMMARIZE_AT, MODELS, T1_MODEL_PRIORITY, T2_MODEL_PRIORITY, T3_MODEL_PRIORITY, VISION_MODEL_PRIORITY, COMPLEXITY_T2_COUNT, THEME_NAMES, DEFAULT_THEME, OLLAMA_BASE_URL, LM_STUDIO_BASE_URL, AZURE_BASE_URL_TEMPLATE, TOOL_NAMES, DEFAULT_APPROVAL_REQUIRED;
131
131
  var init_constants = __esm({
132
132
  "src/constants.ts"() {
133
- CASCADE_VERSION = "0.3.0";
133
+ CASCADE_VERSION = "0.4.0";
134
134
  CASCADE_CONFIG_FILE = ".cascade/config.json";
135
135
  CASCADE_DB_FILE = ".cascade/memory.db";
136
136
  CASCADE_DASHBOARD_SECRET_FILE = ".cascade/dashboard-secret";
@@ -949,19 +949,21 @@ var init_azure = __esm({
949
949
  init_openai();
950
950
  AzureOpenAIProvider = class extends OpenAIProvider {
951
951
  constructor(config, model) {
952
- const baseUrl = config.baseUrl ?? AZURE_BASE_URL_TEMPLATE.replace("{resource}", "YOUR_RESOURCE");
952
+ const rawUrl = config.baseUrl ?? AZURE_BASE_URL_TEMPLATE.replace("{resource}", "YOUR_RESOURCE");
953
+ const endpoint = rawUrl.replace(/\/+$/, "");
953
954
  super(
954
955
  {
955
956
  ...config,
956
- baseUrl: `${baseUrl}/openai/deployments/${config.deploymentName ?? model.id}`
957
+ baseUrl: endpoint
958
+ // Kept for superclass compatibility if it reads it
957
959
  },
958
960
  model
959
961
  );
960
- this.client = new OpenAI__default.default({
962
+ this.client = new OpenAI.AzureOpenAI({
961
963
  apiKey: config.apiKey,
962
- baseURL: `${baseUrl}/openai/deployments/${config.deploymentName ?? model.id}`,
963
- defaultQuery: { "api-version": config.apiVersion ?? "2024-08-01-preview" },
964
- defaultHeaders: { "api-key": config.apiKey ?? "" }
964
+ endpoint,
965
+ deployment: config.deploymentName ?? model.id,
966
+ apiVersion: config.apiVersion ?? "2024-08-01-preview"
965
967
  });
966
968
  }
967
969
  async listModels() {
@@ -3295,7 +3297,7 @@ var CascadeRouter = class _CascadeRouter extends EventEmitter__default.default {
3295
3297
  if (!model) {
3296
3298
  throw new Error(`Configured model "${override}" for ${tier} could not be loaded. Check provider availability and exact model name.`);
3297
3299
  }
3298
- if (model.id !== override) {
3300
+ if (model.id !== override && `${model.provider}:${model.id}` !== override) {
3299
3301
  throw new Error(`Configured model "${override}" for ${tier} resolved to "${model.id}". Use the exact provider model ID or prefix the provider (e.g. gemini:${override}).`);
3300
3302
  }
3301
3303
  this.tierModels.set(tier, model);
@@ -4127,6 +4129,10 @@ HIERARCHY CONTEXT: ${this.hierarchyContext}` : ""),
4127
4129
  await this.context.addMessage({ role: "assistant", content: result.content, toolCalls: result.toolCalls });
4128
4130
  if (!result.toolCalls?.length) {
4129
4131
  if (requiresArtifact) {
4132
+ const artifactCheck = await this.verifyArtifacts(this.assignment);
4133
+ if (artifactCheck.ok) {
4134
+ return { output: result.content, toolCalls: allToolCalls };
4135
+ }
4130
4136
  stalledArtifactIterations += 1;
4131
4137
  if (stalledArtifactIterations >= 2) {
4132
4138
  if (stalledArtifactIterations === 2) {
@@ -4136,15 +4142,22 @@ HIERARCHY CONTEXT: ${this.hierarchyContext}` : ""),
4136
4142
  }
4137
4143
  await this.context.addMessage({
4138
4144
  role: "user",
4139
- content: "You have not yet created and verified the required artifact. Use tools to create the file in the workspace, verify it exists, and inspect the result before concluding."
4145
+ content: `You have not yet created and verified the required artifact. Issues: ${artifactCheck.issues.join("; ")}. Use tools to create the file in the workspace, verify it exists, and inspect the result before concluding.`
4140
4146
  });
4141
4147
  continue;
4142
4148
  }
4143
4149
  return { output: result.content, toolCalls: allToolCalls };
4144
4150
  }
4145
4151
  stalledArtifactIterations = 0;
4146
- if (result.finishReason === "stop" && !requiresArtifact) {
4147
- return { output: result.content, toolCalls: allToolCalls };
4152
+ if (result.finishReason === "stop") {
4153
+ if (requiresArtifact) {
4154
+ const artifactCheck = await this.verifyArtifacts(this.assignment);
4155
+ if (artifactCheck.ok) {
4156
+ return { output: result.content, toolCalls: allToolCalls };
4157
+ }
4158
+ } else {
4159
+ return { output: result.content, toolCalls: allToolCalls };
4160
+ }
4148
4161
  }
4149
4162
  for (const tc of result.toolCalls) {
4150
4163
  allToolCalls.push(tc);
@@ -7615,10 +7628,17 @@ var Cascade = class extends EventEmitter__default.default {
7615
7628
  throw err;
7616
7629
  }
7617
7630
  }
7631
+ isCasualGreeting(prompt) {
7632
+ const casual = /^(hi|hello|hey|greetings|thanks|thank you|thx|bye|goodbye|cya)$/i.test(prompt.trim().replace(/[!?.]+$/, ""));
7633
+ return casual;
7634
+ }
7618
7635
  looksLikeSimpleArtifactTask(prompt) {
7619
7636
  return /create .*\.(txt|md|json|csv)\b/i.test(prompt) && !/(research|compare|thorough|pdf|report|analy[sz]e|architecture|multi-agent)/i.test(prompt);
7620
7637
  }
7621
7638
  async determineComplexity(prompt, workspacePath, conversationHistory = []) {
7639
+ if (this.isCasualGreeting(prompt)) {
7640
+ return "Simple";
7641
+ }
7622
7642
  if (this.looksLikeSimpleArtifactTask(prompt)) {
7623
7643
  return "Simple";
7624
7644
  }
@@ -8925,7 +8945,7 @@ function Repl({ config, workspacePath, themeName, initialPrompt, identityName })
8925
8945
  if (sel.kind === "auto") {
8926
8946
  delete config.models[tierKey];
8927
8947
  } else {
8928
- config.models[tierKey] = sel.modelId;
8948
+ config.models[tierKey] = `${sel.provider}:${sel.modelId}`;
8929
8949
  }
8930
8950
  try {
8931
8951
  const router = cascadeRef.current?.getRouter();
@@ -9483,9 +9503,15 @@ Use /identity <name|id> to switch.`;
9483
9503
  let agentTreeHeight = 0;
9484
9504
  if (state.agentTree && hasActiveOrFailed2(state.agentTree)) {
9485
9505
  agentTreeHeight = 1;
9486
- const childrenCount = state.agentTree.children?.length ?? 0;
9487
- agentTreeHeight += Math.min(childrenCount, 6);
9488
- if (childrenCount > 6) agentTreeHeight += 1;
9506
+ const visibleT2s = state.agentTree.children?.slice(0, 6) ?? [];
9507
+ agentTreeHeight += visibleT2s.length;
9508
+ for (const t2 of visibleT2s) {
9509
+ const t3Count = (t2.children ?? []).filter((c) => c.role === "T3").length;
9510
+ agentTreeHeight += t3Count;
9511
+ }
9512
+ if ((state.agentTree.children?.length ?? 0) > 6) {
9513
+ agentTreeHeight += 1;
9514
+ }
9489
9515
  }
9490
9516
  let timelineHeight = 0;
9491
9517
  if (state.showDetails && treeNodesRef.current.size > 0) {
@@ -9674,6 +9700,13 @@ async function validateConfiguredModels(config) {
9674
9700
  return problems.length ? `Model warnings: ${problems.join(", ")}` : null;
9675
9701
  }
9676
9702
  function inferProviderFromModelId(id, providers) {
9703
+ if (id.includes(":")) {
9704
+ const prefix = id.split(":")[0].toLowerCase();
9705
+ const validProviders = ["anthropic", "openai", "gemini", "azure", "openai-compatible", "ollama"];
9706
+ if (validProviders.includes(prefix)) {
9707
+ return prefix;
9708
+ }
9709
+ }
9677
9710
  const lower = id.toLowerCase();
9678
9711
  if (lower.includes("gpt")) return "openai";
9679
9712
  if (lower.includes("claude")) return "anthropic";