dsh-codebase-chat 0.25.3 → 0.25.6

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/index.js CHANGED
@@ -1620,6 +1620,10 @@ function formatHealthReport(r, lang = "fr") {
1620
1620
  };
1621
1621
  const out = [];
1622
1622
  out.push(`== ${t2.title} \u2014 ${basename(r.projectPath)} ==`);
1623
+ if (r.analyzedFiles === 0) {
1624
+ out.push(lang === "en" ? "No code files detected in this project \u2014 check the path or your .codebase-chat.json ignore rules." : "Aucun fichier de code d\xE9tect\xE9 dans ce projet \u2014 v\xE9rifie le chemin ou les r\xE8gles ignore de .codebase-chat.json.");
1625
+ return out.join("\n");
1626
+ }
1623
1627
  out.push(`${t2.score}: ${r.score}/100 (${r.grade}) \xB7 ${r.analyzedFiles} ${t2.files} \xB7 ${r.importEdges} ${t2.edges}`);
1624
1628
  out.push("");
1625
1629
  out.push(`\u25CF ${t2.cycles} (${r.cycles.length})`);
@@ -1691,6 +1695,10 @@ function formatHealthReportMd(r, lang = "fr") {
1691
1695
  const out = [];
1692
1696
  out.push(`## ${GRADE_ICON[r.grade]} ${t2.title} \u2014 \`${basename(r.projectPath)}\``);
1693
1697
  out.push("");
1698
+ if (r.analyzedFiles === 0) {
1699
+ out.push(lang === "en" ? "_No code files detected in this project \u2014 check the path or your `.codebase-chat.json` ignore rules._" : "_Aucun fichier de code d\xE9tect\xE9 dans ce projet \u2014 v\xE9rifie le chemin ou les r\xE8gles ignore de `.codebase-chat.json`._");
1700
+ return out.join("\n");
1701
+ }
1694
1702
  out.push(`**${t2.score} : ${scoreBar(r.score)} ${r.score}/100 (${r.grade})** \xB7 ${r.analyzedFiles} ${t2.files} \xB7 ${r.importEdges} ${t2.edges}`);
1695
1703
  out.push("");
1696
1704
  out.push(`### ${t2.cycles} \u2014 ${r.cycles.length}`);
@@ -2816,8 +2824,16 @@ function loadLocalModel() {
2816
2824
  throw new Error(`Local model not found: ${spec}`);
2817
2825
  }
2818
2826
  const { getLlama } = await importLlama();
2819
- const llama = await getLlama();
2820
- return llama.loadModel({ modelPath });
2827
+ const cpuOnly = /^(0|off|false|cpu)$/i.test(process.env.CODEBASE_LOCAL_GPU || "");
2828
+ const llama = await getLlama(cpuOnly ? { gpu: false } : {});
2829
+ try {
2830
+ return await llama.loadModel({ modelPath });
2831
+ } catch (err) {
2832
+ if (cpuOnly) throw err;
2833
+ console.error(`[local-llm] GPU load failed (${err instanceof Error ? err.message : err}) \u2014 falling back to CPU. Slower, but works. Set CODEBASE_LOCAL_GPU=off to skip GPU entirely.`);
2834
+ const cpuLlama = await getLlama({ gpu: false });
2835
+ return cpuLlama.loadModel({ modelPath });
2836
+ }
2821
2837
  })();
2822
2838
  modelPromise.catch(() => {
2823
2839
  modelPromise = null;
@@ -2834,7 +2850,13 @@ async function callLocalLlm(prompt, lang = "fr") {
2834
2850
  contextSequence: context.getSequence(),
2835
2851
  systemPrompt: lang === "en" ? "You are a senior codebase analyst. Be precise and cite files with [source: path:line]." : "Tu es un analyste codebase senior. Sois precis et cite les fichiers avec [source: chemin:ligne]."
2836
2852
  });
2837
- return await session.prompt(prompt, { temperature: 0.2, maxTokens: LOCAL_MAX_TOKENS });
2853
+ return await session.prompt(prompt, {
2854
+ temperature: 0.2,
2855
+ maxTokens: LOCAL_MAX_TOKENS,
2856
+ // Small models degenerate into loops at low temperature — penalize
2857
+ // repeated tokens so the answer moves forward instead of echoing.
2858
+ repeatPenalty: { lastTokens: 128, penalty: 1.2, penalizeNewLine: false }
2859
+ });
2838
2860
  } finally {
2839
2861
  await context.dispose();
2840
2862
  }