@syntesseraai/opencode-feature-factory 0.3.4 → 0.3.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.
@@ -5,6 +5,7 @@ export declare class OramaMemoryIndex {
5
5
  private readonly provider;
6
6
  private db;
7
7
  private readonly documents;
8
+ private readonly embedMaxChars;
8
9
  private dimensions;
9
10
  private updatedAt;
10
11
  constructor(directory: string, provider: EmbeddingProvider);
@@ -31,6 +32,7 @@ export declare class OramaMemoryIndex {
31
32
  private persistSnapshot;
32
33
  private writeAtomic;
33
34
  private memoryToEmbeddingInput;
35
+ private prepareEmbeddingInput;
34
36
  private toDocument;
35
37
  private assertEmbeddingDimensions;
36
38
  private embedBatch;
@@ -3,9 +3,23 @@ import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
  const INDEX_VERSION = 1;
5
5
  const EMBED_BATCH_SIZE = 16;
6
+ const DEFAULT_EMBED_MAX_CHARS = 6000;
7
+ const MIN_EMBED_MAX_CHARS = 256;
8
+ const MAX_EMBED_MAX_CHARS = 200_000;
9
+ const TRUNCATION_MARKER = '\n\n...[truncated]...\n\n';
6
10
  function clamp(value, min, max) {
7
11
  return Math.min(Math.max(value, min), max);
8
12
  }
13
+ function resolveEmbedMaxChars(rawValue) {
14
+ if (!rawValue) {
15
+ return DEFAULT_EMBED_MAX_CHARS;
16
+ }
17
+ const parsedValue = Number.parseInt(rawValue, 10);
18
+ if (!Number.isFinite(parsedValue)) {
19
+ return DEFAULT_EMBED_MAX_CHARS;
20
+ }
21
+ return clamp(parsedValue, MIN_EMBED_MAX_CHARS, MAX_EMBED_MAX_CHARS);
22
+ }
9
23
  function isVector(value) {
10
24
  return Array.isArray(value) && value.every((entry) => typeof entry === 'number');
11
25
  }
@@ -77,6 +91,7 @@ export class OramaMemoryIndex {
77
91
  provider;
78
92
  db = null;
79
93
  documents = new Map();
94
+ embedMaxChars = resolveEmbedMaxChars(process.env.FF_LOCAL_RECALL_EMBED_MAX_CHARS);
80
95
  dimensions = null;
81
96
  updatedAt = null;
82
97
  constructor(directory, provider) {
@@ -114,7 +129,7 @@ export class OramaMemoryIndex {
114
129
  .map((document) => toSearchResult(document, 0));
115
130
  return filtered;
116
131
  }
117
- const [queryEmbedding] = await this.provider.embed([query]);
132
+ const [queryEmbedding] = await this.provider.embed([this.prepareEmbeddingInput(query)]);
118
133
  if (!queryEmbedding) {
119
134
  return [];
120
135
  }
@@ -332,7 +347,21 @@ export class OramaMemoryIndex {
332
347
  await rename(tmpPath, filePath);
333
348
  }
334
349
  memoryToEmbeddingInput(memory) {
335
- return `${memory.title}\n\n${memory.body}`.trim();
350
+ return this.prepareEmbeddingInput(`${memory.title}\n\n${memory.body}`);
351
+ }
352
+ prepareEmbeddingInput(input) {
353
+ const normalized = input.trim();
354
+ if (normalized.length <= this.embedMaxChars) {
355
+ return normalized;
356
+ }
357
+ const availableContent = this.embedMaxChars - TRUNCATION_MARKER.length;
358
+ if (availableContent <= 1) {
359
+ return normalized.slice(0, this.embedMaxChars);
360
+ }
361
+ const headLength = Math.ceil(availableContent * 0.8);
362
+ const tailLength = availableContent - headLength;
363
+ const suffix = tailLength > 0 ? normalized.slice(-tailLength) : '';
364
+ return `${normalized.slice(0, headLength)}${TRUNCATION_MARKER}${suffix}`;
336
365
  }
337
366
  toDocument(memory, embedding) {
338
367
  return {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@syntesseraai/opencode-feature-factory",
4
- "version": "0.3.4",
4
+ "version": "0.3.5",
5
5
  "type": "module",
6
6
  "description": "OpenCode plugin for Feature Factory agents - provides sub-agents and skills for validation, review, security, and architecture assessment",
7
7
  "license": "MIT",