ghagga-core 3.1.0 → 3.3.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.
Files changed (113) hide show
  1. package/dist/agents/issue-triage.d.ts +143 -0
  2. package/dist/agents/issue-triage.d.ts.map +1 -0
  3. package/dist/agents/issue-triage.js +230 -0
  4. package/dist/agents/issue-triage.js.map +1 -0
  5. package/dist/agents/prompts.d.ts +41 -1
  6. package/dist/agents/prompts.d.ts.map +1 -1
  7. package/dist/agents/prompts.js +123 -2
  8. package/dist/agents/prompts.js.map +1 -1
  9. package/dist/embed.d.ts +140 -0
  10. package/dist/embed.d.ts.map +1 -1
  11. package/dist/embed.js +288 -0
  12. package/dist/embed.js.map +1 -1
  13. package/dist/enhance/prompt.d.ts +1 -1
  14. package/dist/enhance/prompt.d.ts.map +1 -1
  15. package/dist/graph/builder.d.ts +13 -1
  16. package/dist/graph/builder.d.ts.map +1 -1
  17. package/dist/graph/builder.js +305 -6
  18. package/dist/graph/builder.js.map +1 -1
  19. package/dist/graph/call-chain.d.ts +27 -0
  20. package/dist/graph/call-chain.d.ts.map +1 -1
  21. package/dist/graph/call-chain.js +113 -18
  22. package/dist/graph/call-chain.js.map +1 -1
  23. package/dist/graph/changed-symbols.d.ts +57 -0
  24. package/dist/graph/changed-symbols.d.ts.map +1 -0
  25. package/dist/graph/changed-symbols.js +123 -0
  26. package/dist/graph/changed-symbols.js.map +1 -0
  27. package/dist/graph/extractors/index.d.ts +3 -3
  28. package/dist/graph/extractors/index.d.ts.map +1 -1
  29. package/dist/graph/extractors/index.js +2 -2
  30. package/dist/graph/extractors/index.js.map +1 -1
  31. package/dist/graph/extractors/javascript.d.ts.map +1 -1
  32. package/dist/graph/extractors/javascript.js +89 -3
  33. package/dist/graph/extractors/javascript.js.map +1 -1
  34. package/dist/graph/extractors/rust.d.ts.map +1 -1
  35. package/dist/graph/extractors/rust.js +7 -2
  36. package/dist/graph/extractors/rust.js.map +1 -1
  37. package/dist/graph/extractors/types.d.ts +7 -1
  38. package/dist/graph/extractors/types.d.ts.map +1 -1
  39. package/dist/graph/extractors/typescript.d.ts.map +1 -1
  40. package/dist/graph/extractors/typescript.js +95 -4
  41. package/dist/graph/extractors/typescript.js.map +1 -1
  42. package/dist/graph/index.d.ts +8 -3
  43. package/dist/graph/index.d.ts.map +1 -1
  44. package/dist/graph/index.js +4 -2
  45. package/dist/graph/index.js.map +1 -1
  46. package/dist/graph/loader.d.ts +29 -0
  47. package/dist/graph/loader.d.ts.map +1 -1
  48. package/dist/graph/loader.js +70 -1
  49. package/dist/graph/loader.js.map +1 -1
  50. package/dist/graph/narrow-symbols.d.ts +73 -0
  51. package/dist/graph/narrow-symbols.d.ts.map +1 -0
  52. package/dist/graph/narrow-symbols.js +195 -0
  53. package/dist/graph/narrow-symbols.js.map +1 -0
  54. package/dist/graph/schema.d.ts +117 -4
  55. package/dist/graph/schema.d.ts.map +1 -1
  56. package/dist/graph/schema.js +67 -3
  57. package/dist/graph/schema.js.map +1 -1
  58. package/dist/graph/scip/builder.d.ts +64 -0
  59. package/dist/graph/scip/builder.d.ts.map +1 -0
  60. package/dist/graph/scip/builder.js +268 -0
  61. package/dist/graph/scip/builder.js.map +1 -0
  62. package/dist/graph/scip/merge.d.ts +66 -0
  63. package/dist/graph/scip/merge.d.ts.map +1 -0
  64. package/dist/graph/scip/merge.js +98 -0
  65. package/dist/graph/scip/merge.js.map +1 -0
  66. package/dist/index.d.ts +9 -4
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +5 -2
  69. package/dist/index.js.map +1 -1
  70. package/dist/memory/backfill.d.ts +58 -0
  71. package/dist/memory/backfill.d.ts.map +1 -0
  72. package/dist/memory/backfill.js +85 -0
  73. package/dist/memory/backfill.js.map +1 -0
  74. package/dist/memory/sqlite.d.ts +78 -12
  75. package/dist/memory/sqlite.d.ts.map +1 -1
  76. package/dist/memory/sqlite.js +265 -85
  77. package/dist/memory/sqlite.js.map +1 -1
  78. package/dist/pipeline/gather-context.d.ts.map +1 -1
  79. package/dist/pipeline/gather-context.js +4 -2
  80. package/dist/pipeline/gather-context.js.map +1 -1
  81. package/dist/pipeline/gather-safe.d.ts +24 -4
  82. package/dist/pipeline/gather-safe.d.ts.map +1 -1
  83. package/dist/pipeline/gather-safe.js +42 -6
  84. package/dist/pipeline/gather-safe.js.map +1 -1
  85. package/dist/pipeline/prepare-graph.d.ts +23 -1
  86. package/dist/pipeline/prepare-graph.d.ts.map +1 -1
  87. package/dist/pipeline/prepare-graph.js +119 -3
  88. package/dist/pipeline/prepare-graph.js.map +1 -1
  89. package/dist/pipeline/prepare.d.ts.map +1 -1
  90. package/dist/pipeline/prepare.js +28 -0
  91. package/dist/pipeline/prepare.js.map +1 -1
  92. package/dist/pipeline/state.d.ts +3 -1
  93. package/dist/pipeline/state.d.ts.map +1 -1
  94. package/dist/providers/cli-bridge.d.ts.map +1 -1
  95. package/dist/providers/cli-bridge.js +1 -0
  96. package/dist/providers/cli-bridge.js.map +1 -1
  97. package/dist/providers/gateway-discovery.d.ts +5 -5
  98. package/dist/providers/gateway-discovery.d.ts.map +1 -1
  99. package/dist/providers/gateway-discovery.js +11 -9
  100. package/dist/providers/gateway-discovery.js.map +1 -1
  101. package/dist/providers/gateway.d.ts +87 -0
  102. package/dist/providers/gateway.d.ts.map +1 -1
  103. package/dist/providers/gateway.js +386 -8
  104. package/dist/providers/gateway.js.map +1 -1
  105. package/dist/types.d.ts +61 -2
  106. package/dist/types.d.ts.map +1 -1
  107. package/dist/types.js.map +1 -1
  108. package/dist/utils/concurrency.d.ts.map +1 -1
  109. package/dist/utils/concurrency.js +37 -1
  110. package/dist/utils/concurrency.js.map +1 -1
  111. package/dist/utils/llm-timeout.d.ts +1 -1
  112. package/dist/utils/llm-timeout.d.ts.map +1 -1
  113. package/package.json +10 -8
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Backfill mechanism for per-row embeddings (design D6, spec: "Backfill of
3
+ * NULL-Embedding Observations").
4
+ *
5
+ * Reusable across every storage backend that implements the backfill
6
+ * extension of `MemoryStorage` (`SqliteMemoryStorage`, `PostgresMemoryStorage`).
7
+ * Iterates observations needing an embedding in id-ordered batches, calls
8
+ * the active provider's `embedBatch` ONCE per batch (never N `embed()` calls
9
+ * — spec: "Batched Embedding Calls"), and persists the result.
10
+ *
11
+ * Idempotent + resumable: each batch is selected fresh from storage via
12
+ * `listObservationsNeedingEmbedding`, which only ever matches NULL-embedding
13
+ * rows (plus model/dimension-mismatched rows when `reEmbed` is set) — a row
14
+ * already embedded with a matching model/dimension is never re-selected. A
15
+ * failure mid-run (network error, process crash) leaves all rows updated
16
+ * before the failure committed (SQLite: flushed to disk after each
17
+ * successfully completed batch via `storage.flush()`; PostgreSQL: each
18
+ * `UPDATE` commits per-statement, no explicit transaction) — re-running this
19
+ * function picks up exactly where it left off with no duplicate work.
20
+ */
21
+ import type { EmbeddingProvider } from '../embed.js';
22
+ import type { MemoryStorage } from '../types.js';
23
+ export interface BackfillOptions {
24
+ /** Rows processed per `embedBatch()` call. Defaults to 100 (design D6). */
25
+ batchSize?: number;
26
+ /** Max total rows to process across the whole run. Unlimited when omitted. */
27
+ limit?: number;
28
+ /**
29
+ * Also re-embed rows whose stored `embedding_model`/`embedding_dim`
30
+ * mismatches the active provider — not just NULL-embedding rows. Use
31
+ * after a provider/model swap (design D6, task 8.3 rollout note).
32
+ * Defaults to false.
33
+ */
34
+ reEmbed?: boolean;
35
+ /** Delay (ms) between batches — rate/cost control for paid API providers. Defaults to 0. */
36
+ delayMs?: number;
37
+ /** Optional progress callback, invoked after each successfully committed batch. */
38
+ onProgress?: (progress: {
39
+ batch: number;
40
+ batchSize: number;
41
+ totalProcessed: number;
42
+ }) => void;
43
+ }
44
+ export interface BackfillResult {
45
+ totalProcessed: number;
46
+ totalBatches: number;
47
+ }
48
+ /**
49
+ * Run the backfill against `storage`, using `provider` as the active
50
+ * embedding provider and `activeModel` as the model id to persist alongside
51
+ * each embedding.
52
+ *
53
+ * Throws if `storage` doesn't implement the backfill extension methods
54
+ * (`listObservationsNeedingEmbedding` / `updateObservationEmbedding`) — e.g.
55
+ * `EngramMemoryStorage`, which has no local embedding column to backfill.
56
+ */
57
+ export declare function backfillEmbeddings(storage: MemoryStorage, provider: EmbeddingProvider, activeModel: string, options?: BackfillOptions): Promise<BackfillResult>;
58
+ //# sourceMappingURL=backfill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backfill.d.ts","sourceRoot":"","sources":["../../src/memory/backfill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4FAA4F;IAC5F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC/F;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAID;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAuEzB"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Backfill mechanism for per-row embeddings (design D6, spec: "Backfill of
3
+ * NULL-Embedding Observations").
4
+ *
5
+ * Reusable across every storage backend that implements the backfill
6
+ * extension of `MemoryStorage` (`SqliteMemoryStorage`, `PostgresMemoryStorage`).
7
+ * Iterates observations needing an embedding in id-ordered batches, calls
8
+ * the active provider's `embedBatch` ONCE per batch (never N `embed()` calls
9
+ * — spec: "Batched Embedding Calls"), and persists the result.
10
+ *
11
+ * Idempotent + resumable: each batch is selected fresh from storage via
12
+ * `listObservationsNeedingEmbedding`, which only ever matches NULL-embedding
13
+ * rows (plus model/dimension-mismatched rows when `reEmbed` is set) — a row
14
+ * already embedded with a matching model/dimension is never re-selected. A
15
+ * failure mid-run (network error, process crash) leaves all rows updated
16
+ * before the failure committed (SQLite: flushed to disk after each
17
+ * successfully completed batch via `storage.flush()`; PostgreSQL: each
18
+ * `UPDATE` commits per-statement, no explicit transaction) — re-running this
19
+ * function picks up exactly where it left off with no duplicate work.
20
+ */
21
+ const DEFAULT_BATCH_SIZE = 100;
22
+ /**
23
+ * Run the backfill against `storage`, using `provider` as the active
24
+ * embedding provider and `activeModel` as the model id to persist alongside
25
+ * each embedding.
26
+ *
27
+ * Throws if `storage` doesn't implement the backfill extension methods
28
+ * (`listObservationsNeedingEmbedding` / `updateObservationEmbedding`) — e.g.
29
+ * `EngramMemoryStorage`, which has no local embedding column to backfill.
30
+ */
31
+ export async function backfillEmbeddings(storage, provider, activeModel, options = {}) {
32
+ const listNeeding = storage.listObservationsNeedingEmbedding;
33
+ const updateEmbedding = storage.updateObservationEmbedding;
34
+ if (!listNeeding || !updateEmbedding) {
35
+ throw new Error('[ghagga] This memory storage backend does not support backfill (no local embedding columns).');
36
+ }
37
+ // Bind after the presence check so TS narrows the optional methods to
38
+ // defined function types for the rest of this function.
39
+ const listObservationsNeedingEmbedding = listNeeding.bind(storage);
40
+ const updateObservationEmbedding = updateEmbedding.bind(storage);
41
+ const { batchSize = DEFAULT_BATCH_SIZE, limit, reEmbed = false, delayMs = 0, onProgress, } = options;
42
+ let afterId = 0;
43
+ let totalProcessed = 0;
44
+ let totalBatches = 0;
45
+ while (true) {
46
+ if (limit !== undefined && totalProcessed >= limit)
47
+ break;
48
+ const remaining = limit !== undefined ? limit - totalProcessed : batchSize;
49
+ const currentBatchSize = Math.min(batchSize, remaining);
50
+ if (currentBatchSize <= 0)
51
+ break;
52
+ const rows = await listObservationsNeedingEmbedding({
53
+ afterId,
54
+ limit: currentBatchSize,
55
+ activeModel,
56
+ activeDim: provider.dimension,
57
+ includeMismatched: reEmbed,
58
+ });
59
+ if (rows.length === 0)
60
+ break;
61
+ const embeddings = await provider.embedBatch(rows.map((row) => row.text));
62
+ if (embeddings.length !== rows.length) {
63
+ throw new Error(`[ghagga] embedBatch returned ${embeddings.length} vectors for ${rows.length} inputs — mismatched batch response.`);
64
+ }
65
+ for (let i = 0; i < rows.length; i++) {
66
+ const row = rows[i];
67
+ const embedding = embeddings[i];
68
+ await updateObservationEmbedding(row.id, embedding, activeModel, provider.dimension);
69
+ afterId = row.id;
70
+ }
71
+ if (typeof storage.flush === 'function') {
72
+ await storage.flush();
73
+ }
74
+ totalBatches += 1;
75
+ totalProcessed += rows.length;
76
+ onProgress?.({ batch: totalBatches, batchSize: rows.length, totalProcessed });
77
+ if (rows.length < currentBatchSize)
78
+ break; // drained — fewer rows than requested
79
+ if (delayMs > 0) {
80
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
81
+ }
82
+ }
83
+ return { totalProcessed, totalBatches };
84
+ }
85
+ //# sourceMappingURL=backfill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backfill.js","sourceRoot":"","sources":["../../src/memory/backfill.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,23 @@ export interface SqliteMemoryStorageOptions {
20
20
  * is used for search. When undefined, falls back to keyword-only search.
21
21
  */
22
22
  embeddingProvider?: EmbeddingProvider;
23
+ /**
24
+ * Identifier for the active embedding model (e.g. "text-embedding-3-small").
25
+ * Persisted per-row alongside the vector and compared on read (design D3).
26
+ *
27
+ * NOTE: `EmbeddingProvider` (packages/core/src/embed.ts) does not currently
28
+ * expose a model name, so this is supplied by the caller out-of-band. When
29
+ * omitted, the read guard only enforces dimension compatibility (never
30
+ * throws either way) — the model-mismatch check is a no-op until callers
31
+ * start passing it (wired in PR5).
32
+ */
33
+ embeddingModel?: string;
34
+ /**
35
+ * Bounded cosine candidate set size (design D4). Defaults to 200.
36
+ * Callers should pass `resolveEmbeddingConfig(env).candidateK` (PR1) rather
37
+ * than relying on this default once wired (PR5).
38
+ */
39
+ embeddingCandidateK?: number;
23
40
  }
24
41
  export declare class SqliteMemoryStorage implements MemoryStorage {
25
42
  private db;
@@ -27,6 +44,8 @@ export declare class SqliteMemoryStorage implements MemoryStorage {
27
44
  private dedupWindowMinutes;
28
45
  private decayConfig;
29
46
  private embeddingProvider;
47
+ private embeddingModel;
48
+ private embeddingCandidateK;
30
49
  private pageIndex;
31
50
  private constructor();
32
51
  /**
@@ -50,16 +69,26 @@ export declare class SqliteMemoryStorage implements MemoryStorage {
50
69
  type?: string;
51
70
  }): Promise<MemoryObservationRow[]>;
52
71
  /**
53
- * Hybrid BM25 + semantic search (70% semantic, 30% keyword).
54
- * Only called when embeddingProvider is set.
72
+ * Hybrid keyword + semantic search: unions a bounded cosine candidate set
73
+ * with the keyword (FTS5) candidate set before scoring (spec R5.7-R5.10,
74
+ * design D4/D5). Only called when embeddingProvider is set.
55
75
  *
56
76
  * Strategy:
57
- * 1. Run FTS5 to get keyword candidates (up to limit * 5 to have enough for re-ranking)
58
- * 2. Embed the query
59
- * 3. For each candidate, deserialize its stored embedding and compute cosine similarity
60
- * 4. Candidates without embeddings get cosine_sim = 0 (keyword-only score still applies)
61
- * 5. Combine: final_score = 0.7 * cosine_sim + 0.3 * normalized_bm25
62
- * 6. Sort descending, apply decay filter, return top-k
77
+ * 1. Run FTS5 to get keyword candidates (up to limit * 5), preserving
78
+ * native bm25() order (best match first).
79
+ * 2. Run a bounded, project(+type)-scoped cosine candidate query
80
+ * (embedding IS NOT NULL, ORDER BY last_accessed_at DESC LIMIT K).
81
+ * 3. Compute cosine similarity in JS for candidates that pass the
82
+ * dimension/model read guard (mismatches are excluded, never thrown).
83
+ * 4. Union both sets by id, dedup: an overlapping candidate keeps its
84
+ * real keyword score; a cosine-only candidate gets keyword-score 0.
85
+ * 5. Keyword score uses the unified positional-rank convention
86
+ * `1 - i/(n-1)` over the keyword-ordered list (design D5) — shared
87
+ * with the PostgreSQL backend so both engines score identically
88
+ * post-union.
89
+ * 6. Combine: finalScore = 0.7 * cosineSim + 0.3 * keywordScore.
90
+ * 7. Apply the decay filter, sort descending, cap at limit, update
91
+ * last_accessed_at only for the rows actually returned (R5.10).
63
92
  */
64
93
  private _hybridSearch;
65
94
  saveObservation(data: {
@@ -73,11 +102,14 @@ export declare class SqliteMemoryStorage implements MemoryStorage {
73
102
  severity?: string;
74
103
  }): Promise<MemoryObservationRow>;
75
104
  /**
76
- * Compute embedding buffer for storage.
77
- * Returns the serialized float32 Buffer when embeddingProvider is available,
78
- * or null (no-op) when it is not — enabling graceful degradation.
105
+ * Compute the embedding buffer plus its provider metadata for storage
106
+ * (design D3 — per-row `embedding_model`/`embedding_dim`, task 3.6).
107
+ * Returns all-null when no embeddingProvider is configured (no-op) or when
108
+ * embedding generation fails — a failed embed is non-fatal: the row is
109
+ * still saved with a NULL embedding rather than throwing (spec: Graceful
110
+ * Degradation on Provider/API Failure).
79
111
  */
80
- private _computeEmbeddingBuffer;
112
+ private _computeEmbeddingMeta;
81
113
  createSession(data: {
82
114
  project: string;
83
115
  prNumber?: number;
@@ -125,6 +157,40 @@ export declare class SqliteMemoryStorage implements MemoryStorage {
125
157
  * Returns true if a row was deleted, false otherwise.
126
158
  */
127
159
  deleteNegativeExample(findingHash: string): boolean;
160
+ /**
161
+ * Export the in-memory WASM database and write it to disk WITHOUT closing
162
+ * the underlying handle — shared by close() and flush() (design D6).
163
+ */
164
+ private _writeToDisk;
165
+ /**
166
+ * Durability hook for the backfill script (design D6, task 6.1): flushes
167
+ * the in-memory WASM database to disk after each batch so a mid-run crash
168
+ * loses at most the in-flight batch, not prior progress. Unlike close(),
169
+ * the database handle stays open and usable.
170
+ */
171
+ flush(): Promise<void>;
128
172
  close(): Promise<void>;
173
+ /**
174
+ * List up to `limit` observations needing an embedding for the active
175
+ * provider/model, ordered by id ascending starting after `afterId`.
176
+ * Always matches NULL-embedding rows; with `includeMismatched` also
177
+ * matches rows whose stored `embedding_model`/`embedding_dim` disagree
178
+ * with the active provider (backfill `--re-embed`).
179
+ */
180
+ listObservationsNeedingEmbedding(options: {
181
+ afterId: number;
182
+ limit: number;
183
+ activeModel: string;
184
+ activeDim: number;
185
+ includeMismatched: boolean;
186
+ }): Promise<{
187
+ id: number;
188
+ text: string;
189
+ }[]>;
190
+ /**
191
+ * Persist a backfilled embedding for a single observation (design D6).
192
+ * Metadata-only write — content/updated_at/last_accessed_at are untouched.
193
+ */
194
+ updateObservationEmbedding(id: number, embedding: number[], model: string, dim: number): Promise<void>;
129
195
  }
130
196
  //# sourceMappingURL=sqlite.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/memory/sqlite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/memory/sqlite.ts"],"names":[],"mappings":"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"}