@gethmy/mcp 2.4.6 → 2.5.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.
@@ -1,879 +1,35 @@
1
1
  var __defProp = Object.defineProperty;
2
+ var __returnValue = (v) => v;
3
+ function __exportSetter(name, newValue) {
4
+ this[name] = __returnValue.bind(null, newValue);
5
+ }
2
6
  var __export = (target, all) => {
3
7
  for (var name in all)
4
8
  __defProp(target, name, {
5
9
  get: all[name],
6
10
  enumerable: true,
7
11
  configurable: true,
8
- set: (newValue) => all[name] = () => newValue
12
+ set: __exportSetter.bind(all, name)
9
13
  });
10
14
  };
11
15
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
12
16
 
13
- // ../memory/dist/schema.js
14
- var init_schema = () => {};
15
-
16
- // ../memory/dist/constraints.js
17
- var init_constraints = __esm(() => {
18
- init_schema();
19
- });
20
- // ../memory/dist/client.js
21
- var init_client = __esm(() => {
22
- init_constraints();
23
- });
24
-
25
- // ../memory/dist/graph-walk.js
26
- async function discoverRelatedContext(client, startIds, maxDepth = 2, maxEntities = 20, minConfidence = 0.5) {
27
- const visited = new Set;
28
- const collectedEntities = [];
29
- const collectedRelations = [];
30
- let truncated = false;
31
- const queue = startIds.map((id) => [id, 0]);
32
- for (const id of startIds) {
33
- visited.add(id);
34
- }
35
- while (queue.length > 0) {
36
- const [entityId, depth] = queue.shift();
37
- if (collectedEntities.length >= maxEntities) {
38
- truncated = true;
39
- break;
40
- }
41
- if (depth > maxDepth)
42
- continue;
43
- try {
44
- const entityResult = await client.getMemoryEntity(entityId);
45
- const entity = entityResult.entity;
46
- if (entity) {
47
- collectedEntities.push({
48
- id: entity.id,
49
- type: entity.type,
50
- title: entity.title,
51
- confidence: entity.confidence ?? 1,
52
- memory_tier: entity.memory_tier || "reference"
53
- });
54
- }
55
- if (depth >= maxDepth)
56
- continue;
57
- const related = await client.getRelatedEntities(entityId);
58
- for (const raw of related.outgoing || []) {
59
- const rel = raw;
60
- const relConfidence = rel.confidence ?? 1;
61
- if (relConfidence < minConfidence)
62
- continue;
63
- const target = rel.target;
64
- const targetId = target?.id ?? rel.target_id;
65
- if (targetId && !visited.has(targetId)) {
66
- visited.add(targetId);
67
- queue.push([targetId, depth + 1]);
68
- collectedRelations.push({
69
- id: rel.id,
70
- source_id: entityId,
71
- target_id: targetId,
72
- relation_type: rel.relation_type,
73
- confidence: relConfidence
74
- });
75
- }
76
- }
77
- for (const raw of related.incoming || []) {
78
- const rel = raw;
79
- const relConfidence = rel.confidence ?? 1;
80
- if (relConfidence < minConfidence)
81
- continue;
82
- const source = rel.source;
83
- const sourceId = source?.id ?? rel.source_id;
84
- if (sourceId && !visited.has(sourceId)) {
85
- visited.add(sourceId);
86
- queue.push([sourceId, depth + 1]);
87
- collectedRelations.push({
88
- id: rel.id,
89
- source_id: sourceId,
90
- target_id: entityId,
91
- relation_type: rel.relation_type,
92
- confidence: relConfidence
93
- });
94
- }
95
- }
96
- } catch {}
97
- }
98
- return {
99
- entities: collectedEntities,
100
- relations: collectedRelations,
101
- depth: maxDepth,
102
- truncated
103
- };
104
- }
105
-
106
- // ../memory/dist/lifecycle.js
107
- function checkPromotion(currentTier, accessCount, confidence, createdAt) {
108
- const ageDays = (Date.now() - new Date(createdAt).getTime()) / (1000 * 60 * 60 * 24);
109
- const base = {
110
- eligible: false,
111
- targetTier: null,
112
- reason: null,
113
- currentTier,
114
- accessCount,
115
- confidence,
116
- ageDays
117
- };
118
- if (currentTier === "draft") {
119
- const rules = PROMOTION_RULES.draftToEpisode;
120
- if (accessCount >= rules.minAccessCount && confidence >= rules.minConfidence && ageDays >= rules.minAgeDays) {
121
- return {
122
- ...base,
123
- eligible: true,
124
- targetTier: "episode",
125
- reason: `Accessed ${accessCount} times (≥${rules.minAccessCount}), confidence ${confidence} (≥${rules.minConfidence}), age ${Math.round(ageDays)}d (≥${rules.minAgeDays}d)`
126
- };
127
- }
128
- }
129
- if (currentTier === "episode") {
130
- const rules = PROMOTION_RULES.episodeToReference;
131
- if (accessCount >= rules.minAccessCount && confidence >= rules.minConfidence && ageDays >= rules.minAgeDays) {
132
- return {
133
- ...base,
134
- eligible: true,
135
- targetTier: "reference",
136
- reason: `Accessed ${accessCount} times (≥${rules.minAccessCount}), confidence ${confidence} (≥${rules.minConfidence}), age ${Math.round(ageDays)}d (≥${rules.minAgeDays}d)`
137
- };
138
- }
139
- }
140
- return base;
141
- }
142
- var PROMOTION_RULES;
143
- var init_lifecycle = __esm(() => {
144
- PROMOTION_RULES = {
145
- draftToEpisode: {
146
- minAccessCount: 5,
147
- minConfidence: 0.8,
148
- minAgeDays: 1
149
- },
150
- episodeToReference: {
151
- minAccessCount: 10,
152
- minConfidence: 0.9,
153
- minAgeDays: 7
154
- }
155
- };
156
- });
157
- // ../memory/dist/sync.js
158
- var init_sync = () => {};
159
-
160
- // ../memory/dist/index.js
161
- var init_dist = __esm(() => {
162
- init_client();
163
- init_constraints();
164
- init_lifecycle();
165
- init_schema();
166
- init_sync();
167
- });
168
-
169
- // src/context-assembly.ts
170
- var exports_context_assembly = {};
171
- __export(exports_context_assembly, {
172
- trackSessionAssembly: () => trackSessionAssembly,
173
- recordContextFeedback: () => recordContextFeedback,
174
- mapToContextEntity: () => mapToContextEntity,
175
- getSessionAssemblyId: () => getSessionAssemblyId,
176
- getCachedManifest: () => getCachedManifest,
177
- expandQuery: () => expandQuery,
178
- computeRelevanceScore: () => computeRelevanceScore,
179
- cacheManifest: () => cacheManifest,
180
- assembleContext: () => assembleContext
181
- });
182
- function estimateTokens(text) {
183
- return Math.ceil(text.length / 4);
184
- }
185
- function passesQualityGate(entity) {
186
- const content = entity.content.trim();
187
- if (content.length < 50)
188
- return false;
189
- const normalizedTitle = entity.title.toLowerCase().replace(/[^a-z0-9\s]/g, "").trim();
190
- const normalizedContent = content.toLowerCase().replace(/[^a-z0-9\s]/g, "").trim();
191
- if (normalizedContent.length < normalizedTitle.length * 1.5) {
192
- return false;
193
- }
194
- if (entity.type === "pattern" && /recurring .+ \(\d+ instances\)/i.test(entity.title)) {
195
- const lines = content.split(`
196
- `).filter((l) => l.trim().length > 0);
197
- const bulletLines = lines.filter((l) => l.trim().startsWith("- "));
198
- if (bulletLines.length > lines.length * 0.6)
199
- return false;
200
- }
201
- if (entity.type === "procedure") {
202
- const stepCount = (content.match(/^\d+\.\s/gm) || []).length;
203
- if (stepCount < 3)
204
- return false;
205
- }
206
- return true;
207
- }
208
- function generateAssemblyId() {
209
- return `ctx_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
210
- }
211
- function truncateContent(content, maxTokens) {
212
- const currentTokens = estimateTokens(content);
213
- if (currentTokens <= maxTokens) {
214
- return { text: content, truncated: false };
215
- }
216
- const paragraphs = content.split(/\n\n+/);
217
- let result = paragraphs[0];
218
- for (let i = 1;i < paragraphs.length; i++) {
219
- const lines = paragraphs[i].split(`
220
- `).filter((l) => l.startsWith("- ") || l.startsWith("* "));
221
- if (lines.length > 0) {
222
- const bulletSection = lines.join(`
223
- `);
224
- if (estimateTokens(result + `
225
-
226
- ` + bulletSection) <= maxTokens) {
227
- result += `
228
-
229
- ` + bulletSection;
230
- }
231
- }
232
- }
233
- if (estimateTokens(result) > maxTokens) {
234
- const maxChars = maxTokens * 4;
235
- result = result.slice(0, maxChars - 3) + "...";
236
- }
237
- return { text: result, truncated: true };
238
- }
239
- function escapeRegex(str) {
240
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
241
- }
242
- function expandQuery(taskContext) {
243
- const queries = [taskContext];
244
- const lowerQueries = [taskContext.toLowerCase()];
245
- const words = taskContext.toLowerCase().split(/\W+/).filter((w) => w.length > 2);
246
- const expandableWords = words.filter((w) => QUERY_SYNONYMS[w]);
247
- for (const word of expandableWords) {
248
- const synonyms = QUERY_SYNONYMS[word];
249
- if (!synonyms)
250
- continue;
251
- const variation = taskContext.replace(new RegExp(`\\b${escapeRegex(word)}\\b`, "gi"), synonyms[0]);
252
- const lowerVariation = variation.toLowerCase();
253
- if (lowerVariation !== taskContext.toLowerCase() && !lowerQueries.includes(lowerVariation)) {
254
- queries.push(variation);
255
- lowerQueries.push(lowerVariation);
256
- }
257
- if (queries.length >= MAX_QUERY_VARIATIONS)
258
- break;
259
- }
260
- if (words.length >= 3) {
261
- const keyPhrases = words.filter((w) => ![
262
- "the",
263
- "and",
264
- "for",
265
- "with",
266
- "this",
267
- "that",
268
- "from",
269
- "into"
270
- ].includes(w)).slice(0, 4).join(" ");
271
- if (!lowerQueries.includes(keyPhrases)) {
272
- queries.push(keyPhrases);
273
- }
274
- }
275
- return queries.slice(0, MAX_QUERY_VARIATIONS);
276
- }
277
- function computeRelevanceScore(entity, taskContext, cardLabels, graphRelations) {
278
- const reasons = [];
279
- let score = 0;
280
- const hasRrfScore = entity.rrf_score !== undefined && entity.rrf_score > 0;
281
- if (hasRrfScore) {
282
- const normalizedRrf = Math.min(entity.rrf_score / 0.04, 1);
283
- const rrfContribution = normalizedRrf * 0.3;
284
- score += rrfContribution;
285
- reasons.push(`hybrid_search(rrf=${entity.rrf_score.toFixed(4)})`);
286
- }
287
- const textMatchWeight = hasRrfScore ? 0.15 : 0.4;
288
- const taskWords = new Set(taskContext.toLowerCase().split(/\W+/).filter((w) => w.length > 2));
289
- const entityWords = new Set(`${entity.title} ${entity.content}`.toLowerCase().split(/\W+/).filter((w) => w.length > 2));
290
- const overlap = [...taskWords].filter((w) => entityWords.has(w));
291
- if (overlap.length > 0) {
292
- const textScore = Math.min(overlap.length / Math.max(taskWords.size, 1), 1) * textMatchWeight;
293
- score += textScore;
294
- reasons.push(`text_match(${overlap.length} words)`);
295
- }
296
- if (cardLabels.length > 0 && entity.tags.length > 0) {
297
- const labelSet = new Set(cardLabels.map((l) => l.toLowerCase()));
298
- const tagOverlap = entity.tags.filter((t) => labelSet.has(t.toLowerCase()));
299
- if (tagOverlap.length > 0) {
300
- const tagScore = tagOverlap.length / cardLabels.length * 0.3;
301
- score += tagScore;
302
- reasons.push(`tag_match(${tagOverlap.join(",")})`);
303
- }
304
- }
305
- score += entity.confidence * 0.15;
306
- if (entity.confidence >= 0.9) {
307
- reasons.push("high_confidence");
308
- }
309
- if (entity.last_accessed_at) {
310
- const daysSinceAccess = (Date.now() - new Date(entity.last_accessed_at).getTime()) / (1000 * 60 * 60 * 24);
311
- const halfLife = { draft: 7, episode: 30, reference: 180 }[entity.memory_tier];
312
- const recencyScore = 0.5 ** (daysSinceAccess / halfLife) * 0.1;
313
- score += recencyScore;
314
- if (daysSinceAccess < 7)
315
- reasons.push("recently_accessed");
316
- }
317
- if (entity.access_count > 0) {
318
- const freqScore = Math.log10(entity.access_count + 1) * 0.05;
319
- score += Math.min(freqScore, 0.1);
320
- if (entity.access_count >= 5)
321
- reasons.push(`frequently_used(${entity.access_count})`);
322
- }
323
- const usefulnessScore = entity.metadata?.usefulness_score ?? 0;
324
- if (usefulnessScore >= 3) {
325
- const usefulnessBoost = Math.min(usefulnessScore / 20, 0.15);
326
- score += usefulnessBoost;
327
- reasons.push(`useful(${usefulnessScore})`);
328
- } else if (usefulnessScore === 0 && entity.access_count >= 5) {
329
- score -= 0.02;
330
- reasons.push("low_usefulness");
331
- }
332
- if (entity.type === "procedure") {
333
- score += 0.1;
334
- reasons.push("procedure_boost");
335
- }
336
- if (graphRelations && graphRelations.length > 0) {
337
- const entityRelations = graphRelations.filter((r) => r.source_id === entity.id || r.target_id === entity.id);
338
- if (entityRelations.length > 0) {
339
- let bestBonus = 0;
340
- let bestRelType = "";
341
- for (const rel of entityRelations) {
342
- const bonus = RELATION_BONUSES[rel.relation_type] ?? 0.1;
343
- if (bonus > bestBonus) {
344
- bestBonus = bonus;
345
- bestRelType = rel.relation_type;
346
- }
347
- }
348
- score += bestBonus;
349
- reasons.push(`graph_walk(${bestRelType})`);
350
- }
351
- }
352
- score = Math.max(0, Math.min(score, 1));
353
- const tierWeight = TIER_WEIGHTS[entity.memory_tier];
354
- score *= tierWeight;
355
- return { score, reasons };
356
- }
357
- async function assembleContext(options) {
358
- const {
359
- workspaceId,
360
- projectId,
361
- taskContext,
362
- cardLabels = [],
363
- tokenBudget = DEFAULT_TOKEN_BUDGET,
364
- client: client2,
365
- graphWalkEnabled = true,
366
- queryExpansionEnabled = true,
367
- enableLlmReranking = false,
368
- rerankFn
369
- } = options;
370
- const assemblyId = generateAssemblyId();
371
- const manifest = {
372
- assemblyId,
373
- timestamp: new Date().toISOString(),
374
- included: [],
375
- excluded: [],
376
- budgetUsed: 0,
377
- budgetTotal: tokenBudget,
378
- tierBreakdown: {
379
- draft: { count: 0, tokens: 0 },
380
- episode: { count: 0, tokens: 0 },
381
- reference: { count: 0, tokens: 0 }
382
- }
383
- };
384
- const candidates = [];
385
- const queries = queryExpansionEnabled ? expandQuery(taskContext) : [taskContext];
386
- const searchResults = await Promise.allSettled(queries.map((query) => client2.searchMemoryEntities(workspaceId, query, {
387
- project_id: projectId,
388
- limit: 30
389
- })));
390
- const candidateIds = new Set;
391
- for (const result of searchResults) {
392
- if (result.status !== "fulfilled")
393
- continue;
394
- if (result.value.entities?.length > 0) {
395
- for (const raw of result.value.entities) {
396
- const entity = mapToContextEntity(raw);
397
- if (!candidateIds.has(entity.id)) {
398
- candidateIds.add(entity.id);
399
- candidates.push(entity);
400
- }
401
- }
402
- }
403
- }
404
- if (candidates.length < 10 && projectId) {
405
- try {
406
- const listResult = await client2.listMemoryEntities({
407
- workspace_id: workspaceId,
408
- project_id: projectId,
409
- limit: 30
410
- });
411
- if (listResult.entities?.length > 0) {
412
- for (const raw of listResult.entities) {
413
- const entity = mapToContextEntity(raw);
414
- if (!candidateIds.has(entity.id)) {
415
- candidateIds.add(entity.id);
416
- candidates.push(entity);
417
- }
418
- }
419
- }
420
- } catch {}
421
- }
422
- if (candidates.length < 20) {
423
- try {
424
- const wsResult = await client2.listMemoryEntities({
425
- workspace_id: workspaceId,
426
- scope: "workspace",
427
- limit: 20
428
- });
429
- if (wsResult.entities?.length > 0) {
430
- for (const raw of wsResult.entities) {
431
- const entity = mapToContextEntity(raw);
432
- if (!candidateIds.has(entity.id)) {
433
- candidateIds.add(entity.id);
434
- candidates.push(entity);
435
- }
436
- }
437
- }
438
- } catch {}
439
- }
440
- let graphRelations = [];
441
- if (graphWalkEnabled && candidates.length > 0) {
442
- try {
443
- const seedCandidates = [...candidates].sort((a, b) => (b.rrf_score ?? 0) - (a.rrf_score ?? 0)).slice(0, GRAPH_WALK_SEED_COUNT);
444
- const seedIds = seedCandidates.map((c) => c.id);
445
- const walkResult = await discoverRelatedContext(client2, seedIds, GRAPH_WALK_MAX_DEPTH, GRAPH_WALK_MAX_ENTITIES, GRAPH_WALK_MIN_CONFIDENCE);
446
- graphRelations = walkResult.relations;
447
- const newEntityIds = walkResult.entities.filter((e) => !candidateIds.has(e.id)).map((e) => e.id);
448
- if (newEntityIds.length > 0) {
449
- const fetchResults = await Promise.allSettled(newEntityIds.map((id) => client2.getMemoryEntity(id)));
450
- for (const result of fetchResults) {
451
- if (result.status !== "fulfilled" || !result.value.entity)
452
- continue;
453
- const mapped = mapToContextEntity(result.value.entity);
454
- candidateIds.add(mapped.id);
455
- candidates.push(mapped);
456
- }
457
- }
458
- } catch {}
459
- }
460
- if (candidates.length === 0) {
461
- return {
462
- context: "",
463
- manifest,
464
- memories: []
465
- };
466
- }
467
- const qualityCandidates = candidates.filter((entity) => {
468
- if (passesQualityGate(entity))
469
- return true;
470
- manifest.excluded.push({
471
- entityId: entity.id,
472
- title: entity.title,
473
- type: entity.type,
474
- tier: entity.memory_tier,
475
- relevanceScore: 0,
476
- reason: "failed_quality_gate"
477
- });
478
- return false;
479
- });
480
- if (qualityCandidates.length === 0) {
481
- return {
482
- context: "",
483
- manifest,
484
- memories: []
485
- };
486
- }
487
- const scored = qualityCandidates.map((entity) => {
488
- const { score, reasons } = computeRelevanceScore(entity, taskContext, cardLabels, graphRelations.length > 0 ? graphRelations : undefined);
489
- return { entity, score, reasons };
490
- });
491
- scored.sort((a, b) => b.score - a.score);
492
- if (enableLlmReranking && rerankFn && scored.length >= RERANK_MIN_CANDIDATES) {
493
- const topN = scored.slice(0, RERANK_TOP_N);
494
- const scoreRange = topN[0].score - topN[topN.length - 1].score;
495
- if (scoreRange <= RERANK_CLUSTER_THRESHOLD) {
496
- try {
497
- const rerankCandidates = topN.map((s) => ({
498
- id: s.entity.id,
499
- title: s.entity.title,
500
- snippet: s.entity.content.slice(0, 200)
501
- }));
502
- const rerankedIds = await rerankFn(taskContext, rerankCandidates);
503
- const idOrder = new Map(rerankedIds.map((id, i) => [id, i]));
504
- topN.sort((a, b) => {
505
- const aIdx = idOrder.get(a.entity.id) ?? 999;
506
- const bIdx = idOrder.get(b.entity.id) ?? 999;
507
- return aIdx - bIdx;
508
- });
509
- scored.splice(0, topN.length, ...topN);
510
- } catch {}
511
- }
512
- }
513
- const procedureBudget = Math.floor(tokenBudget * PROCEDURE_BUDGET_FRACTION);
514
- const remainingBudget = tokenBudget - procedureBudget;
515
- const tierBudgets = {
516
- reference: Math.floor(remainingBudget * TIER_BUDGET_ALLOCATION.reference),
517
- episode: Math.floor(remainingBudget * TIER_BUDGET_ALLOCATION.episode),
518
- draft: Math.floor(remainingBudget * TIER_BUDGET_ALLOCATION.draft)
519
- };
520
- const tierUsed = {
521
- reference: 0,
522
- episode: 0,
523
- draft: 0
524
- };
525
- let procedureUsed = 0;
526
- const included = [];
527
- let totalUsed = 0;
528
- let referenceCount = 0;
529
- for (const item of scored) {
530
- if (item.entity.memory_tier === "reference" && item.entity.type !== "procedure" && referenceCount < MIN_REFERENCE_SLOTS) {
531
- const { text, truncated } = truncateContent(item.entity.content, MAX_TOKENS_PER_ENTITY);
532
- const tokens = estimateTokens(`### ${item.entity.title}
533
- ${text}`);
534
- if (totalUsed + tokens <= tokenBudget) {
535
- included.push({ ...item, tokens, truncated });
536
- item.entity.content = text;
537
- totalUsed += tokens;
538
- tierUsed.reference += tokens;
539
- referenceCount++;
540
- }
541
- }
542
- }
543
- const includedIds = new Set(included.map((i) => i.entity.id));
544
- const procedureCandidates = scored.filter((item) => item.entity.type === "procedure" && !includedIds.has(item.entity.id));
545
- for (const item of procedureCandidates) {
546
- if (item.score < MIN_RELEVANCE_THRESHOLD) {
547
- manifest.excluded.push({
548
- entityId: item.entity.id,
549
- title: item.entity.title,
550
- type: item.entity.type,
551
- tier: item.entity.memory_tier,
552
- relevanceScore: item.score,
553
- reason: "below_relevance_threshold"
554
- });
555
- continue;
556
- }
557
- const { text, truncated } = truncateContent(item.entity.content, MAX_TOKENS_PER_ENTITY);
558
- const tokens = estimateTokens(`### ${item.entity.title}
559
- ${text}`);
560
- if (procedureUsed + tokens > procedureBudget) {
561
- const totalRemaining = tokenBudget - totalUsed;
562
- if (tokens > totalRemaining) {
563
- manifest.excluded.push({
564
- entityId: item.entity.id,
565
- title: item.entity.title,
566
- type: item.entity.type,
567
- tier: item.entity.memory_tier,
568
- relevanceScore: item.score,
569
- reason: "procedure_budget_exceeded"
570
- });
571
- continue;
572
- }
573
- }
574
- if (totalUsed + tokens > tokenBudget) {
575
- manifest.excluded.push({
576
- entityId: item.entity.id,
577
- title: item.entity.title,
578
- type: item.entity.type,
579
- tier: item.entity.memory_tier,
580
- relevanceScore: item.score,
581
- reason: "total_budget_exceeded"
582
- });
583
- continue;
584
- }
585
- included.push({ ...item, tokens, truncated });
586
- item.entity.content = text;
587
- totalUsed += tokens;
588
- procedureUsed += tokens;
589
- includedIds.add(item.entity.id);
590
- }
591
- for (const item of scored) {
592
- if (includedIds.has(item.entity.id))
593
- continue;
594
- if (item.entity.type === "procedure")
595
- continue;
596
- if (item.score < MIN_RELEVANCE_THRESHOLD) {
597
- manifest.excluded.push({
598
- entityId: item.entity.id,
599
- title: item.entity.title,
600
- type: item.entity.type,
601
- tier: item.entity.memory_tier,
602
- relevanceScore: item.score,
603
- reason: "below_relevance_threshold"
604
- });
605
- continue;
606
- }
607
- const tier = item.entity.memory_tier;
608
- const { text, truncated } = truncateContent(item.entity.content, MAX_TOKENS_PER_ENTITY);
609
- const tokens = estimateTokens(`### ${item.entity.title}
610
- ${text}`);
611
- if (tierUsed[tier] + tokens > tierBudgets[tier]) {
612
- const totalRemaining = tokenBudget - totalUsed;
613
- if (tokens > totalRemaining) {
614
- manifest.excluded.push({
615
- entityId: item.entity.id,
616
- title: item.entity.title,
617
- type: item.entity.type,
618
- tier,
619
- relevanceScore: item.score,
620
- reason: "budget_exceeded"
621
- });
622
- continue;
623
- }
624
- }
625
- if (totalUsed + tokens > tokenBudget) {
626
- manifest.excluded.push({
627
- entityId: item.entity.id,
628
- title: item.entity.title,
629
- type: item.entity.type,
630
- tier,
631
- relevanceScore: item.score,
632
- reason: "total_budget_exceeded"
633
- });
634
- continue;
635
- }
636
- included.push({ ...item, tokens, truncated });
637
- item.entity.content = text;
638
- totalUsed += tokens;
639
- tierUsed[tier] += tokens;
640
- includedIds.add(item.entity.id);
641
- }
642
- manifest.budgetUsed = totalUsed;
643
- const procedureItems = included.filter((i) => i.entity.type === "procedure");
644
- manifest.tierBreakdown = {
645
- reference: {
646
- count: included.filter((i) => i.entity.memory_tier === "reference" && i.entity.type !== "procedure").length,
647
- tokens: tierUsed.reference
648
- },
649
- episode: {
650
- count: included.filter((i) => i.entity.memory_tier === "episode" && i.entity.type !== "procedure").length,
651
- tokens: tierUsed.episode
652
- },
653
- draft: {
654
- count: included.filter((i) => i.entity.memory_tier === "draft" && i.entity.type !== "procedure").length,
655
- tokens: tierUsed.draft
656
- }
657
- };
658
- manifest.procedureBreakdown = {
659
- count: procedureItems.length,
660
- tokens: procedureUsed,
661
- budget: procedureBudget
662
- };
663
- for (const item of included) {
664
- manifest.included.push({
665
- entityId: item.entity.id,
666
- title: item.entity.title,
667
- type: item.entity.type,
668
- tier: item.entity.memory_tier,
669
- relevanceScore: item.score,
670
- reasons: item.reasons,
671
- tokenCount: item.tokens,
672
- truncated: item.truncated
673
- });
674
- }
675
- const contextSections = [];
676
- const nonProcedureItems = included.filter((i) => i.entity.type !== "procedure");
677
- if (included.length > 0) {
678
- if (procedureItems.length > 0) {
679
- contextSections.push(`## Procedures (${procedureItems.length} loaded, ${procedureUsed}/${procedureBudget} tokens)`);
680
- for (const item of procedureItems) {
681
- const tags = item.entity.tags.length > 0 ? ` [${item.entity.tags.join(", ")}]` : "";
682
- const tierLabel = item.entity.memory_tier !== "reference" ? ` (${item.entity.memory_tier})` : "";
683
- contextSections.push(`
684
- ### ${item.entity.title} (confidence: ${item.entity.confidence})${tierLabel}${tags}`);
685
- contextSections.push(item.entity.content);
686
- }
687
- }
688
- if (nonProcedureItems.length > 0) {
689
- contextSections.push(`
690
- ## Relevant Memories (${nonProcedureItems.length} loaded, ${manifest.excluded.length} excluded)`);
691
- contextSections.push(`*Assembly: ${assemblyId} | Budget: ${totalUsed}/${tokenBudget} tokens*`);
692
- for (const item of nonProcedureItems) {
693
- const tags = item.entity.tags.length > 0 ? ` [${item.entity.tags.join(", ")}]` : "";
694
- const tierLabel = item.entity.memory_tier !== "reference" ? ` (${item.entity.memory_tier})` : "";
695
- contextSections.push(`
696
- ### ${item.entity.title} (${item.entity.type}, confidence: ${item.entity.confidence})${tierLabel}${tags}`);
697
- contextSections.push(item.entity.content);
698
- }
699
- }
700
- }
701
- incrementAccessCounts(client2, included.map((i) => i.entity.id)).catch(() => {});
702
- promoteEligibleEntities(client2, included.map((i) => i.entity)).catch(() => {});
703
- return {
704
- context: contextSections.join(`
705
- `),
706
- manifest,
707
- memories: included.map((i) => i.entity)
708
- };
709
- }
710
- function mapToContextEntity(raw) {
711
- const e = raw;
712
- return {
713
- id: e.id,
714
- type: e.type,
715
- title: e.title,
716
- content: e.content,
717
- confidence: e.confidence ?? 1,
718
- tags: e.tags || [],
719
- memory_tier: e.memory_tier || "reference",
720
- access_count: e.access_count || 0,
721
- last_accessed_at: e.last_accessed_at || null,
722
- created_at: e.created_at || "",
723
- updated_at: e.updated_at || "",
724
- metadata: e.metadata ?? undefined,
725
- rrf_score: e.rrf_score ?? undefined,
726
- fts_rank: e.fts_rank ?? undefined,
727
- semantic_rank: e.semantic_rank ?? undefined
728
- };
729
- }
730
- async function incrementAccessCounts(client2, entityIds) {
731
- if (entityIds.length === 0)
732
- return;
733
- try {
734
- await client2.batchTouchMemoryEntities(entityIds);
735
- } catch {
736
- await Promise.allSettled(entityIds.map((id) => client2.touchMemoryEntity(id)));
737
- }
738
- }
739
- async function promoteEligibleEntities(client2, entities) {
740
- for (const entity of entities) {
741
- if (entity.memory_tier === "reference")
742
- continue;
743
- if (!entity.created_at)
744
- continue;
745
- const promotion = checkPromotion(entity.memory_tier, entity.access_count + 1, entity.confidence, entity.created_at);
746
- if (promotion.eligible && promotion.targetTier) {
747
- try {
748
- await client2.updateMemoryEntity(entity.id, {
749
- memory_tier: promotion.targetTier,
750
- metadata: {
751
- ...entity.metadata || {},
752
- promoted_at: new Date().toISOString(),
753
- promotion_reason: promotion.reason,
754
- promoted_from: entity.memory_tier
755
- }
756
- });
757
- } catch {}
758
- }
759
- }
760
- }
761
- function cacheManifest(manifest) {
762
- if (manifestCache.size >= MAX_CACHE_SIZE) {
763
- const firstKey = manifestCache.keys().next().value;
764
- if (firstKey)
765
- manifestCache.delete(firstKey);
766
- }
767
- manifestCache.set(manifest.assemblyId, manifest);
768
- }
769
- function getCachedManifest(assemblyId) {
770
- return manifestCache.get(assemblyId);
771
- }
772
- function trackSessionAssembly(cardId, assemblyId) {
773
- if (sessionAssemblyMap.size >= MAX_SESSION_MAP_SIZE) {
774
- const firstKey = sessionAssemblyMap.keys().next().value;
775
- if (firstKey)
776
- sessionAssemblyMap.delete(firstKey);
777
- }
778
- sessionAssemblyMap.set(cardId, assemblyId);
779
- }
780
- function getSessionAssemblyId(cardId) {
781
- return sessionAssemblyMap.get(cardId);
782
- }
783
- async function recordContextFeedback(client2, cardId, sessionStatus, progressPercent, hadBlockers) {
784
- const assemblyId = sessionAssemblyMap.get(cardId);
785
- if (!assemblyId)
786
- return { adjusted: 0 };
787
- const manifest = manifestCache.get(assemblyId);
788
- if (!manifest || manifest.included.length === 0)
789
- return { adjusted: 0 };
790
- let adjusted = 0;
791
- const isSuccess = sessionStatus === "completed" && (progressPercent ?? 0) >= 100;
792
- for (const entry of manifest.included) {
793
- try {
794
- if (isSuccess) {
795
- const { entity } = await client2.getMemoryEntity(entry.entityId);
796
- const e = entity;
797
- const currentUsefulness = e.metadata?.usefulness_score ?? 0;
798
- const newConfidence = Math.min((e.confidence ?? 0.5) + 0.05, 1);
799
- await client2.updateMemoryEntity(entry.entityId, {
800
- confidence: newConfidence,
801
- metadata: {
802
- usefulness_score: currentUsefulness + 1,
803
- last_feedback_at: new Date().toISOString()
804
- }
805
- });
806
- adjusted++;
807
- } else if (hadBlockers) {
808
- const { entity } = await client2.getMemoryEntity(entry.entityId);
809
- const e = entity;
810
- const newConfidence = Math.max((e.confidence ?? 0.5) - 0.02, 0.1);
811
- await client2.updateMemoryEntity(entry.entityId, {
812
- confidence: newConfidence,
813
- metadata: {
814
- last_feedback_at: new Date().toISOString()
815
- }
816
- });
817
- adjusted++;
818
- }
819
- } catch {}
820
- }
821
- sessionAssemblyMap.delete(cardId);
822
- return { adjusted };
823
- }
824
- var DEFAULT_TOKEN_BUDGET = 4000, MAX_TOKENS_PER_ENTITY = 500, MIN_RELEVANCE_THRESHOLD = 0.15, TIER_WEIGHTS, PROCEDURE_BUDGET_FRACTION = 0.15, TIER_BUDGET_ALLOCATION, MIN_REFERENCE_SLOTS = 1, GRAPH_WALK_MAX_DEPTH = 1, GRAPH_WALK_MAX_ENTITIES = 10, GRAPH_WALK_MIN_CONFIDENCE = 0.5, GRAPH_WALK_SEED_COUNT = 5, MAX_QUERY_VARIATIONS = 4, RERANK_CLUSTER_THRESHOLD = 0.05, RERANK_TOP_N = 10, RERANK_MIN_CANDIDATES = 5, RELATION_BONUSES, QUERY_SYNONYMS, manifestCache, MAX_CACHE_SIZE = 50, sessionAssemblyMap, MAX_SESSION_MAP_SIZE = 100;
825
- var init_context_assembly = __esm(() => {
826
- init_dist();
827
- TIER_WEIGHTS = {
828
- reference: 1,
829
- episode: 0.7,
830
- draft: 0.4
831
- };
832
- TIER_BUDGET_ALLOCATION = {
833
- reference: 0.6,
834
- episode: 0.3,
835
- draft: 0.1
836
- };
837
- RELATION_BONUSES = {
838
- depends_on: 0.15,
839
- resolved_by: 0.2,
840
- relates_to: 0.1,
841
- implements: 0.15,
842
- blocks: 0.15,
843
- references: 0.1,
844
- extends: 0.1,
845
- caused_by: 0.15
846
- };
847
- QUERY_SYNONYMS = {
848
- auth: ["authentication", "authorization", "session"],
849
- authentication: ["auth", "session", "sign-in"],
850
- login: ["sign-in", "authentication", "session"],
851
- bug: ["error", "issue", "defect", "problem"],
852
- error: ["exception", "failure", "issue"],
853
- fix: ["resolve", "patch", "repair", "correct"],
854
- deploy: ["deployment", "release", "ship", "publish"],
855
- test: ["testing", "spec", "assertion", "verify"],
856
- config: ["configuration", "settings", "setup"],
857
- db: ["database", "storage", "persistence"],
858
- database: ["storage", "persistence", "data store"],
859
- api: ["endpoint", "route", "service"],
860
- ui: ["frontend", "component", "view"],
861
- perf: ["performance", "speed", "latency"],
862
- performance: ["speed", "latency", "optimization"]
863
- };
864
- manifestCache = new Map;
865
- sessionAssemblyMap = new Map;
866
- });
867
-
868
17
  // src/prompt-builder.ts
869
18
  var exports_prompt_builder = {};
870
19
  __export(exports_prompt_builder, {
20
+ proposePromptVariant: () => proposePromptVariant,
871
21
  inferCategoryFromLabels: () => inferCategoryFromLabels,
872
22
  getRoleFraming: () => getRoleFraming,
873
23
  getAvailableVariants: () => getAvailableVariants,
874
24
  getAvailableCategories: () => getAvailableCategories,
875
- generatePrompt: () => generatePrompt
25
+ generatePrompt: () => generatePrompt,
26
+ computeContentHash: () => computeContentHash,
27
+ PROMPT_TEMPLATE_VERSION: () => PROMPT_TEMPLATE_VERSION
876
28
  });
29
+ import { createHash, randomUUID } from "node:crypto";
30
+ function computeContentHash(prompt) {
31
+ return createHash("sha256").update(prompt).digest("hex");
32
+ }
877
33
  function inferCategoryFromLabels(labels) {
878
34
  for (const label of labels) {
879
35
  const normalizedName = label.name.toLowerCase().trim();
@@ -891,7 +47,7 @@ function inferCategoryFromLabels(labels) {
891
47
  function getRoleFraming(category) {
892
48
  return DEFAULT_ROLE_FRAMINGS[category];
893
49
  }
894
- function estimateTokens2(text) {
50
+ function estimateTokens(text) {
895
51
  return Math.ceil(text.length / 4);
896
52
  }
897
53
  function formatSubtasks(subtasks) {
@@ -1054,8 +210,11 @@ ${customConstraints}`);
1054
210
  linkedCardCount: links.length,
1055
211
  memoryCount
1056
212
  },
1057
- tokenEstimate: estimateTokens2(prompt),
1058
- ...assemblyId && { assemblyId }
213
+ tokenEstimate: estimateTokens(prompt),
214
+ ...assemblyId && { assemblyId },
215
+ promptId: randomUUID(),
216
+ contentHash: computeContentHash(prompt),
217
+ version: PROMPT_TEMPLATE_VERSION
1059
218
  };
1060
219
  }
1061
220
  function extractSessionInsights(assembledContext) {
@@ -1137,7 +296,26 @@ function getAvailableCategories() {
1137
296
  function getAvailableVariants() {
1138
297
  return ["analysis", "draft", "execute"];
1139
298
  }
1140
- var LABEL_CATEGORY_MAP, DEFAULT_ROLE_FRAMINGS, VARIANT_INSTRUCTIONS;
299
+ async function proposePromptVariant(contentHash, fetchCohort) {
300
+ if (!contentHash)
301
+ return null;
302
+ const cohort = await fetchCohort(contentHash);
303
+ if (!cohort || cohort.length < VARIANT_MIN_COHORT)
304
+ return null;
305
+ const completed = cohort.filter((r) => r.status === "completed" && (r.progressPercent ?? 0) >= 100 && !r.hadBlockers).length;
306
+ const completionRate = completed / cohort.length;
307
+ if (completionRate >= VARIANT_COMPLETION_THRESHOLD)
308
+ return null;
309
+ const blockerRate = cohort.filter((r) => r.hadBlockers).length / cohort.length;
310
+ const framingHint = blockerRate >= 0.4 ? "Cohort hits frequent blockers — try a more diagnostic framing (require root-cause + repro before any fix)." : "Cohort frequently stalls without finishing — try a more action-forcing framing (smaller subtasks, explicit DoD checklist).";
311
+ return {
312
+ contentHash,
313
+ cohortSize: cohort.length,
314
+ completionRate,
315
+ framingHint
316
+ };
317
+ }
318
+ var PROMPT_TEMPLATE_VERSION = 1, LABEL_CATEGORY_MAP, DEFAULT_ROLE_FRAMINGS, VARIANT_INSTRUCTIONS, VARIANT_MIN_COHORT = 10, VARIANT_COMPLETION_THRESHOLD = 0.4;
1141
319
  var init_prompt_builder = __esm(() => {
1142
320
  LABEL_CATEGORY_MAP = {
1143
321
  bug: "bug",
@@ -1496,6 +674,26 @@ function getMemoryDir() {
1496
674
  return join(homedir(), ".harmony", "memory");
1497
675
  }
1498
676
 
677
+ // ../harmony-shared/dist/cardLinks.js
678
+ var LINK_TYPE_INVERSES = {
679
+ relates_to: "relates_to",
680
+ blocks: "is_blocked_by",
681
+ duplicates: "is_duplicated_by",
682
+ is_part_of: "has_part"
683
+ };
684
+ function getDisplayLinkType(linkType, direction) {
685
+ if (direction === "outgoing")
686
+ return linkType;
687
+ return LINK_TYPE_INVERSES[linkType];
688
+ }
689
+ // ../harmony-shared/dist/constants.js
690
+ var TIMINGS = {
691
+ SEARCH_DEBOUNCE: 300,
692
+ AUTOSAVE_DEBOUNCE: 1000,
693
+ TOAST_DURATION: 3000,
694
+ QUERY_STALE_TIME: 1000 * 60 * 5,
695
+ QUERY_GC_TIME: 1000 * 60 * 60 * 24
696
+ };
1499
697
  // src/api-client.ts
1500
698
  var RETRY_CONFIG = {
1501
699
  maxRetries: 3,
@@ -1592,6 +790,9 @@ class HarmonyApiClient {
1592
790
  setApiKey(apiKey) {
1593
791
  this.apiKey = apiKey;
1594
792
  }
793
+ getApiKey() {
794
+ return this.apiKey;
795
+ }
1595
796
  async request(method, path, body, options) {
1596
797
  await requestSemaphore.acquire();
1597
798
  try {
@@ -1841,22 +1042,6 @@ class HarmonyApiClient {
1841
1042
  const query = params.toString() ? `?${params.toString()}` : "";
1842
1043
  return this.request("GET", `/cards/${cardId}/agent-context${query}`);
1843
1044
  }
1844
- async getAgentProfile(workspaceId, agentIdentifier) {
1845
- const params = new URLSearchParams({
1846
- workspace_id: workspaceId,
1847
- agent_identifier: agentIdentifier
1848
- });
1849
- return this.request("GET", `/agent-profiles?${params.toString()}`);
1850
- }
1851
- async listAgentProfiles(workspaceId) {
1852
- const params = new URLSearchParams({ workspace_id: workspaceId });
1853
- return this.request("GET", `/agent-profiles?${params.toString()}`);
1854
- }
1855
- async refreshAgentProfiles(workspaceId) {
1856
- return this.request("POST", "/agent-profiles/refresh", {
1857
- workspace_id: workspaceId
1858
- });
1859
- }
1860
1045
  async createMemoryEntity(data) {
1861
1046
  return this.request("POST", "/memory/entities", data);
1862
1047
  }
@@ -1881,6 +1066,8 @@ class HarmonyApiClient {
1881
1066
  params.set("limit", String(options.limit));
1882
1067
  if (options.offset !== undefined)
1883
1068
  params.set("offset", String(options.offset));
1069
+ if (options.include_superseded)
1070
+ params.set("include_superseded", "true");
1884
1071
  return this.request("GET", `/memory/entities?${params.toString()}`);
1885
1072
  }
1886
1073
  async getMemoryEntity(entityId) {
@@ -2046,10 +1233,35 @@ class HarmonyApiClient {
2046
1233
  async generateApiKey(name) {
2047
1234
  return this.request("POST", "/api-keys", { name });
2048
1235
  }
1236
+ async recordPromptHistory(data) {
1237
+ return this.request("POST", "/prompt-history", data);
1238
+ }
1239
+ async recordPromptHistoryFeedback(sessionId, outcome) {
1240
+ return this.request("POST", "/prompt-history/feedback", {
1241
+ sessionId,
1242
+ outcome
1243
+ });
1244
+ }
1245
+ async getPromptHistoryCohort(contentHash) {
1246
+ const params = new URLSearchParams({ content_hash: contentHash });
1247
+ return this.request("GET", `/prompt-history/cohort?${params.toString()}`);
1248
+ }
2049
1249
  async generateCardPrompt(options) {
2050
- const { assembleContext: assembleContext2, cacheManifest: cacheManifest2, generatePrompt: generatePrompt2 } = await loadPromptModules();
1250
+ const { generatePrompt: generatePrompt2 } = await loadPromptModules();
2051
1251
  const cardResult = await this.getCard(options.cardId);
2052
1252
  const cardData = cardResult.card;
1253
+ try {
1254
+ const linksResult = await this.getCardLinks(options.cardId);
1255
+ const rawLinks = linksResult.links || [];
1256
+ cardData.links = rawLinks.filter((l) => l.target_card).map((l) => ({
1257
+ target_card: l.target_card,
1258
+ direction: l.direction,
1259
+ display_type: getDisplayLinkType(l.link_type, l.direction)
1260
+ }));
1261
+ } catch (err) {
1262
+ const msg = err instanceof Error ? err.message : String(err);
1263
+ console.debug(`[generateCardPrompt] getCardLinks failed: ${msg}`);
1264
+ }
2053
1265
  let columnData = null;
2054
1266
  const projectIdForBoard = options.projectId || cardData.project_id;
2055
1267
  if (projectIdForBoard) {
@@ -2062,51 +1274,29 @@ class HarmonyApiClient {
2062
1274
  } catch {}
2063
1275
  }
2064
1276
  const variant = options.variant || "execute";
2065
- let assembledContextStr;
2066
- let assemblyId;
1277
+ const assembledContextStr = undefined;
1278
+ const assemblyId = undefined;
2067
1279
  let memories;
2068
1280
  try {
2069
1281
  if (options.workspaceId && cardData.title) {
2070
- const cardLabels = (cardData.labels || []).map((l) => l.name);
2071
- const taskContext = [cardData.title, cardData.description || ""].filter(Boolean).join(" ");
2072
- const assembled = await assembleContext2({
2073
- workspaceId: options.workspaceId,
2074
- projectId: options.projectId,
2075
- taskContext,
2076
- cardLabels,
2077
- cardId: cardData.id,
2078
- client: this
1282
+ const memoryResult = await this.searchMemoryEntities(options.workspaceId, cardData.title, {
1283
+ project_id: options.projectId,
1284
+ limit: 5
2079
1285
  });
2080
- if (assembled.context) {
2081
- assembledContextStr = assembled.context;
2082
- assemblyId = assembled.manifest.assemblyId;
2083
- cacheManifest2(assembled.manifest);
1286
+ if (memoryResult.entities?.length > 0) {
1287
+ memories = memoryResult.entities.map((e) => ({
1288
+ id: e.id,
1289
+ type: e.type,
1290
+ title: e.title,
1291
+ content: e.content,
1292
+ confidence: e.confidence,
1293
+ tags: e.tags || []
1294
+ }));
2084
1295
  }
2085
1296
  }
2086
1297
  } catch (err) {
2087
1298
  const msg = err instanceof Error ? err.message : String(err);
2088
- console.debug(`[generateCardPrompt] Context assembly failed: ${msg}`);
2089
- try {
2090
- if (options.workspaceId && cardData.title) {
2091
- const memoryResult = await this.searchMemoryEntities(options.workspaceId, cardData.title, {
2092
- project_id: options.projectId,
2093
- limit: 5
2094
- });
2095
- if (memoryResult.entities?.length > 0) {
2096
- memories = memoryResult.entities.map((e) => ({
2097
- id: e.id,
2098
- type: e.type,
2099
- title: e.title,
2100
- content: e.content,
2101
- confidence: e.confidence,
2102
- tags: e.tags || []
2103
- }));
2104
- }
2105
- }
2106
- } catch (fallbackErr) {
2107
- const fallbackMsg = fallbackErr instanceof Error ? fallbackErr.message : String(fallbackErr);
2108
- console.debug(`[generateCardPrompt] Memory fallback also failed: ${fallbackMsg}`);
2109
- }
1299
+ console.debug(`[generateCardPrompt] Memory search failed: ${msg}`);
2110
1300
  }
2111
1301
  const result = generatePrompt2({
2112
1302
  card: cardData,
@@ -2118,6 +1308,25 @@ class HarmonyApiClient {
2118
1308
  assembledContext: assembledContextStr,
2119
1309
  assemblyId
2120
1310
  });
1311
+ try {
1312
+ await this.recordPromptHistory({
1313
+ cardId: cardData.id,
1314
+ generatedPrompt: result.prompt,
1315
+ variant,
1316
+ contextIncluded: {
1317
+ assemblyId: result.assemblyId ?? null,
1318
+ tokenEstimate: result.tokenEstimate,
1319
+ contextSummary: result.contextSummary
1320
+ },
1321
+ sessionId: options.sessionId ?? null,
1322
+ contentHash: result.contentHash,
1323
+ templateVersion: result.version,
1324
+ confidence: 0.5
1325
+ });
1326
+ } catch (err) {
1327
+ const msg = err instanceof Error ? err.message : String(err);
1328
+ console.debug(`[generateCardPrompt] prompt_history persistence failed: ${msg}`);
1329
+ }
2121
1330
  return {
2122
1331
  ...result,
2123
1332
  cardId: cardData.id,
@@ -2129,27 +1338,22 @@ class HarmonyApiClient {
2129
1338
  var _promptModules = null;
2130
1339
  async function loadPromptModules() {
2131
1340
  if (!_promptModules) {
2132
- const [ca, pb] = await Promise.all([
2133
- Promise.resolve().then(() => (init_context_assembly(), exports_context_assembly)),
2134
- Promise.resolve().then(() => (init_prompt_builder(), exports_prompt_builder))
2135
- ]);
1341
+ const pb = await Promise.resolve().then(() => (init_prompt_builder(), exports_prompt_builder));
2136
1342
  _promptModules = {
2137
- assembleContext: ca.assembleContext,
2138
- cacheManifest: ca.cacheManifest,
2139
1343
  generatePrompt: pb.generatePrompt
2140
1344
  };
2141
1345
  }
2142
1346
  return _promptModules;
2143
1347
  }
2144
- var client2 = null;
1348
+ var client = null;
2145
1349
  function getClient() {
2146
- if (!client2) {
2147
- client2 = new HarmonyApiClient;
1350
+ if (!client) {
1351
+ client = new HarmonyApiClient;
2148
1352
  }
2149
- return client2;
1353
+ return client;
2150
1354
  }
2151
1355
  function resetClient() {
2152
- client2 = null;
1356
+ client = null;
2153
1357
  }
2154
1358
  export {
2155
1359
  signupUser,