@gamaze/hicortex 0.16.4 → 0.16.5

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/llm.d.ts CHANGED
@@ -29,6 +29,8 @@ export interface LlmConfig {
29
29
  maxTokens?: number;
30
30
  /** Toggle thinking on the openai-compat path for the heavy phases. Absent = no kwarg sent. */
31
31
  enableThinking?: boolean;
32
+ /** Context window for the ollama fast tier (completeOllama). Falls back to 2048. */
33
+ numCtx?: number;
32
34
  /** Optional separate endpoint for reflect-tier LLM (e.g. remote Ollama with larger model). */
33
35
  reflectBaseUrl?: string;
34
36
  reflectApiKey?: string;
package/dist/llm.js CHANGED
@@ -208,6 +208,9 @@ function applyTierTuningOverlay(llmConfig, savedConfig) {
208
208
  if (thinking !== undefined) {
209
209
  llmConfig.enableThinking = thinking;
210
210
  }
211
+ if (savedConfig.numCtx !== undefined) {
212
+ llmConfig.numCtx = (0, config_read_js_1.readPositiveConfig)(savedConfig, "numCtx", 2048);
213
+ }
211
214
  }
212
215
  /**
213
216
  * Resolve an LlmConfig from a saved ~/.hicortex/config.json object.
@@ -539,10 +542,11 @@ class LlmClient {
539
542
  */
540
543
  async completeFast(prompt, maxTokens) {
541
544
  const tokens = maxTokens ?? this.config.maxTokens ?? 2048;
542
- // No `thinking` arg: scoring is excluded from the thinking toggle (it's the
543
- // local fast tier; on ollama it's think:false regardless). completeFast never
544
- // threads thinking, so chat_template_kwargs is never sent for scoring.
545
- return this.complete(this.config.model, prompt, tokens, 600_000);
545
+ // Scoring is the fast tier: numCtx (default 2048, ~850-token prompts) is threaded
546
+ // so ONLY this tier gets the smaller context window the heavy tiers keep 32768
547
+ // (preserves detectChunkSize's chunk-sizing). thinking is not threaded (scoring is
548
+ // excluded from the thinking toggle; ollama is think:false regardless).
549
+ return this.complete(this.config.model, prompt, tokens, 600_000, undefined, this.config.numCtx ?? 2048);
546
550
  }
547
551
  /**
548
552
  * Reflect-tier completion (nightly reflection, needs reasoning).
@@ -608,9 +612,14 @@ class LlmClient {
608
612
  apiKey,
609
613
  provider,
610
614
  });
615
+ // numCtx intentionally NOT forwarded here: only the heavy tiers route through
616
+ // completeWithOverride (there is no fastBaseUrl/fast-tier override), and they
617
+ // must land on completeOllama's 32768 default to preserve detectChunkSize. If a
618
+ // fast-tier override is ever added, thread numCtx here too — else the fast tier
619
+ // would silently revert to 32768 (the original bug, reintroduced).
611
620
  return tempClient.complete(model, prompt, maxTokens, timeoutMs, thinking);
612
621
  }
613
- async complete(model, prompt, maxTokens, timeoutMs, thinking) {
622
+ async complete(model, prompt, maxTokens, timeoutMs, thinking, numCtx) {
614
623
  if (this.isRateLimited) {
615
624
  throw new RateLimitError(this.rateLimitedUntil - Date.now());
616
625
  }
@@ -618,7 +627,7 @@ class LlmClient {
618
627
  let lastErr;
619
628
  for (let attempt = 0; attempt <= retryDelays.length; attempt++) {
620
629
  try {
621
- return await this.completeOnce(model, prompt, maxTokens, timeoutMs, thinking);
630
+ return await this.completeOnce(model, prompt, maxTokens, timeoutMs, thinking, numCtx);
622
631
  }
623
632
  catch (err) {
624
633
  lastErr = err instanceof Error ? err : new Error(String(err));
@@ -635,12 +644,12 @@ class LlmClient {
635
644
  }
636
645
  throw lastErr;
637
646
  }
638
- async completeOnce(model, prompt, maxTokens, timeoutMs, thinking) {
647
+ async completeOnce(model, prompt, maxTokens, timeoutMs, thinking, numCtx) {
639
648
  if (this.config.provider === "claude-cli") {
640
649
  return this.completeClaude(model, prompt, timeoutMs);
641
650
  }
642
651
  if (this.config.provider === "ollama") {
643
- return this.completeOllama(model, prompt, maxTokens, timeoutMs);
652
+ return this.completeOllama(model, prompt, maxTokens, timeoutMs, numCtx);
644
653
  }
645
654
  if (this.config.provider === "anthropic") {
646
655
  return this.completeAnthropic(model, prompt, maxTokens, timeoutMs);
@@ -676,7 +685,7 @@ class LlmClient {
676
685
  /**
677
686
  * Ollama: use /api/generate with think:false (important for qwen3.5 models).
678
687
  */
679
- async completeOllama(model, prompt, maxTokens, timeoutMs) {
688
+ async completeOllama(model, prompt, maxTokens, timeoutMs, numCtx) {
680
689
  const url = `${this.config.baseUrl.replace(/\/$/, "")}/api/generate`;
681
690
  // Ollama can take minutes to process large contexts — use streaming to avoid
682
691
  // Node.js fetch headers timeout (default ~300s kills long Ollama inferences)
@@ -688,7 +697,14 @@ class LlmClient {
688
697
  prompt,
689
698
  stream: true,
690
699
  think: false,
691
- options: { num_predict: maxTokens, num_ctx: 32768 },
700
+ // num_ctx: threaded from completeFast (the fast/scoring tier) via the numCtx
701
+ // param. The fast tier passes the numCtx config key (default 2048; scoring
702
+ // prompts are ~850 tokens) to minimize the KV/prompt-cache footprint that, at
703
+ // 32768, accumulated past available RAM on memory-constrained boxes during long
704
+ // consolidations and swap-thrashed the nightly. The heavy tiers
705
+ // (completeDistill/Reflect/Classify) do NOT pass numCtx → default 32768, which
706
+ // preserves detectChunkSize's chunk-sizing (it packs ~60% of context per chunk).
707
+ options: { num_predict: maxTokens, num_ctx: numCtx ?? 32768 },
692
708
  }),
693
709
  signal: AbortSignal.timeout(timeoutMs),
694
710
  });
package/dist/types.d.ts CHANGED
@@ -303,6 +303,16 @@ export interface HicortexConfig {
303
303
  * See #220.
304
304
  */
305
305
  enableThinking?: boolean;
306
+ /**
307
+ * Context window for the ollama FAST tier (importance scoring via `completeFast`).
308
+ * Default 2048. Scoring prompts are ~850 tokens, so 2048 fits with headroom. The
309
+ * prior hardcoded 32768 — still the default for the heavy distill/reflect/classify
310
+ * tiers (which need it for `detectChunkSize`'s chunk-sizing) — made the KV-cache +
311
+ * prompt-cache accumulate past available RAM on memory-constrained boxes during long
312
+ * consolidations and swap-thrash the nightly. Applies to scoring only; raise if a
313
+ * scoring prompt actually needs more.
314
+ */
315
+ numCtx?: number;
306
316
  }
307
317
  /** A config-owned life-sphere domain (see HicortexConfig.domains). */
308
318
  export interface DomainDef {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gamaze/hicortex",
3
- "version": "0.16.4",
3
+ "version": "0.16.5",
4
4
  "description": "Self-learning memory for AI agents — experience captured automatically, distilled into lessons overnight, shared across your whole fleet. Works with Hermes, OpenClaw, Claude Code, and Pi.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {