@botcord/daemon 0.2.84 → 0.2.86

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.
@@ -7,7 +7,7 @@ import type { RuntimeProbeEntry } from "./adapters/runtimes.js";
7
7
 
8
8
  const MODEL_LIST_TIMEOUT_MS = 5000;
9
9
  const MODEL_LIST_MAX_BUFFER = 16 * 1024 * 1024;
10
- const RUNTIME_CATALOG_CACHE_VERSION = 1;
10
+ const RUNTIME_CATALOG_CACHE_VERSION = 2;
11
11
  const RUNTIME_CATALOG_CACHE_FRESH_MS = 10 * 60 * 1000;
12
12
  const DEFAULT_RUNTIME_CATALOG_CACHE_DIR = path.join(
13
13
  homedir(),
@@ -136,7 +136,7 @@ function runtimeCatalogStrategy(entry: RuntimeProbeEntry): RuntimeCatalogStrateg
136
136
  discoverFresh: () => discoverDeepseekCatalog(entry.result.path),
137
137
  fallback: () => ({
138
138
  models: DEEPSEEK_FALLBACK_MODELS.slice(),
139
- parameters: discoverDeepseekParameters(),
139
+ parameters: discoverDeepseekParameters(entry.result.path),
140
140
  }),
141
141
  };
142
142
  case "kimi-cli":
@@ -433,7 +433,7 @@ function discoverCodexParameters(rawCatalog: string | null): RuntimeParameterPro
433
433
  function discoverDeepseekCatalog(command: string | undefined): RuntimeModelDiscovery {
434
434
  return {
435
435
  models: discoverDeepseekModels(command),
436
- parameters: discoverDeepseekParameters(),
436
+ parameters: discoverDeepseekParameters(command),
437
437
  };
438
438
  }
439
439
 
@@ -457,8 +457,9 @@ export function parseDeepseekModelList(raw: string): RuntimeModelProbe[] | undef
457
457
  return out.length ? out : undefined;
458
458
  }
459
459
 
460
- function discoverDeepseekParameters(): RuntimeParameterProbe[] {
460
+ function discoverDeepseekParameters(command?: string): RuntimeParameterProbe[] {
461
461
  const config = readConfigScalars(path.join(homedir(), ".deepseek", "config.toml"));
462
+ const reasoningEffortValues = discoverDeepseekReasoningEffortValues(command);
462
463
  return [
463
464
  compactParameter({
464
465
  id: "model",
@@ -480,8 +481,9 @@ function discoverDeepseekParameters(): RuntimeParameterProbe[] {
480
481
  compactParameter({
481
482
  id: "reasoning_effort",
482
483
  displayName: "Reasoning effort",
483
- type: "string",
484
- flag: "reasoning_effort",
484
+ type: reasoningEffortValues.length > 0 ? "enum" : "string",
485
+ flag: "--reasoning-effort",
486
+ values: reasoningEffortValues.length > 0 ? reasoningEffortValues : undefined,
485
487
  defaultValue: config.reasoning_effort,
486
488
  source: config.reasoning_effort ? "config" : "cli",
487
489
  }),
@@ -504,6 +506,44 @@ function discoverDeepseekParameters(): RuntimeParameterProbe[] {
504
506
  ];
505
507
  }
506
508
 
509
+ function discoverDeepseekReasoningEffortValues(command: string | undefined): string[] {
510
+ const candidates = deepseekRuntimeTemplateCandidates(command);
511
+ const values = new Set<string>();
512
+ for (const candidate of candidates) {
513
+ try {
514
+ const raw = readFileSync(candidate)
515
+ .toString("latin1")
516
+ .replace(/[^\x20-\x7E]+/g, "\n");
517
+ const templateRe =
518
+ /Thinking mode \(DeepSeek V4 reasoning effort\):[\s\S]{0,256}?#\s*((?:"[^"]+"\s*(?:\|\s*)?)+)/g;
519
+ for (const match of raw.matchAll(templateRe)) {
520
+ const line = match[1] ?? "";
521
+ for (const valueMatch of line.matchAll(/"([^"]+)"/g)) {
522
+ const value = valueMatch[1]?.trim();
523
+ if (value && /^[A-Za-z0-9_.-]+$/.test(value)) values.add(value);
524
+ }
525
+ }
526
+ } catch {
527
+ // Try the next candidate; runtime discovery should stay best-effort.
528
+ }
529
+ }
530
+ return Array.from(values);
531
+ }
532
+
533
+ function deepseekRuntimeTemplateCandidates(command: string | undefined): string[] {
534
+ if (!command) return [];
535
+ const candidates = new Set<string>();
536
+ if (existsSync(command)) candidates.add(command);
537
+ const dir = path.dirname(command);
538
+ for (const candidate of [
539
+ path.join(dir, "deepseek-tui"),
540
+ path.join(dir, "downloads", "deepseek-tui"),
541
+ ]) {
542
+ if (existsSync(candidate)) candidates.add(candidate);
543
+ }
544
+ return Array.from(candidates);
545
+ }
546
+
507
547
  function discoverKimiCatalog(): RuntimeModelDiscovery {
508
548
  const configPath = path.join(homedir(), ".kimi", "config.toml");
509
549
  if (!existsSync(configPath)) return {};
@@ -23,6 +23,19 @@ export interface SoftSkillEntry {
23
23
  mtimeMs: number;
24
24
  }
25
25
 
26
+ export interface AgentSkillSnapshotEntry {
27
+ name: string;
28
+ source: string;
29
+ description?: string;
30
+ mtimeMs: number;
31
+ }
32
+
33
+ export interface AgentSkillSnapshot {
34
+ agentId: string;
35
+ skills: AgentSkillSnapshotEntry[];
36
+ probedAt: number;
37
+ }
38
+
26
39
  export interface SkillIndexOptions {
27
40
  extraDirs?: string[];
28
41
  includeGlobal?: boolean;
@@ -70,7 +83,7 @@ export function scanSoftSkills(
70
83
  if (!existsSync(root.dir)) continue;
71
84
  let children: string[];
72
85
  try {
73
- children = readdirSync(root.dir);
86
+ children = readdirSync(root.dir).sort((a, b) => a.localeCompare(b));
74
87
  } catch {
75
88
  continue;
76
89
  }
@@ -105,15 +118,30 @@ export function scanSoftSkills(
105
118
  }
106
119
 
107
120
  return Array.from(byName.values())
108
- .sort((a, b) => a.name.localeCompare(b.name))
109
- .slice(0, MAX_SKILLS);
121
+ .sort((a, b) => a.name.localeCompare(b.name));
122
+ }
123
+
124
+ export function collectAgentSkillSnapshot(
125
+ agentId: string,
126
+ opts: SkillIndexOptions = {},
127
+ ): AgentSkillSnapshot {
128
+ return {
129
+ agentId,
130
+ skills: scanSoftSkills(agentId, opts).map((skill) => ({
131
+ name: skill.name,
132
+ source: skill.source.startsWith("agent-") ? "workspace" : "runtime-global",
133
+ ...(skill.description ? { description: skill.description } : {}),
134
+ mtimeMs: skill.mtimeMs,
135
+ })),
136
+ probedAt: Date.now(),
137
+ };
110
138
  }
111
139
 
112
140
  export function buildSoftSkillIndexPrompt(
113
141
  agentId: string,
114
142
  opts: SkillIndexOptions = {},
115
143
  ): string | null {
116
- const skills = scanSoftSkills(agentId, opts);
144
+ const skills = scanSoftSkills(agentId, opts).slice(0, MAX_SKILLS);
117
145
  if (skills.length === 0) return null;
118
146
 
119
147
  const lines = [