aiwcli 0.12.3 → 0.12.7
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/bin/dev.cmd +3 -3
- package/bin/dev.js +16 -16
- package/bin/run.cmd +3 -3
- package/bin/run.js +21 -21
- package/dist/commands/branch.js +7 -2
- package/dist/lib/bmad-installer.js +37 -37
- package/dist/lib/terminal.d.ts +2 -0
- package/dist/lib/terminal.js +57 -7
- package/dist/templates/CLAUDE.md +205 -205
- package/dist/templates/_shared/.claude/commands/handoff-resume.md +12 -64
- package/dist/templates/_shared/.claude/commands/handoff.md +12 -198
- package/dist/templates/_shared/.claude/settings.json +65 -65
- package/dist/templates/_shared/.codex/workflows/handoff.md +226 -226
- package/dist/templates/_shared/.windsurf/workflows/handoff.md +226 -226
- package/dist/templates/_shared/handoff-system/CLAUDE.md +421 -0
- package/dist/templates/_shared/{lib-ts/handoff → handoff-system/lib}/document-generator.ts +215 -216
- package/dist/templates/_shared/{lib-ts/handoff → handoff-system/lib}/handoff-reader.ts +157 -158
- package/dist/templates/_shared/{scripts → handoff-system/scripts}/resume_handoff.ts +373 -373
- package/dist/templates/_shared/{scripts → handoff-system/scripts}/save_handoff.ts +469 -358
- package/dist/templates/_shared/handoff-system/workflows/handoff-resume.md +66 -0
- package/dist/templates/_shared/{workflows → handoff-system/workflows}/handoff.md +254 -254
- package/dist/templates/_shared/hooks-ts/_utils/git-state.ts +2 -2
- package/dist/templates/_shared/hooks-ts/archive_plan.ts +159 -159
- package/dist/templates/_shared/hooks-ts/context_monitor.ts +147 -147
- package/dist/templates/_shared/hooks-ts/file-suggestion.ts +128 -128
- package/dist/templates/_shared/hooks-ts/pre_compact.ts +49 -49
- package/dist/templates/_shared/hooks-ts/session_end.ts +196 -183
- package/dist/templates/_shared/hooks-ts/session_start.ts +163 -151
- package/dist/templates/_shared/hooks-ts/task_create_capture.ts +48 -48
- package/dist/templates/_shared/hooks-ts/task_update_capture.ts +74 -74
- package/dist/templates/_shared/hooks-ts/user_prompt_submit.ts +93 -93
- package/dist/templates/_shared/lib-ts/CLAUDE.md +367 -367
- package/dist/templates/_shared/lib-ts/base/atomic-write.ts +138 -138
- package/dist/templates/_shared/lib-ts/base/constants.ts +303 -303
- package/dist/templates/_shared/lib-ts/base/git-state.ts +58 -58
- package/dist/templates/_shared/lib-ts/base/hook-utils.ts +582 -582
- package/dist/templates/_shared/lib-ts/base/inference.ts +301 -301
- package/dist/templates/_shared/lib-ts/base/logger.ts +247 -247
- package/dist/templates/_shared/lib-ts/base/state-io.ts +202 -130
- package/dist/templates/_shared/lib-ts/base/stop-words.ts +184 -184
- package/dist/templates/_shared/lib-ts/base/subprocess-utils.ts +56 -0
- package/dist/templates/_shared/lib-ts/base/utils.ts +184 -184
- package/dist/templates/_shared/lib-ts/context/context-formatter.ts +566 -560
- package/dist/templates/_shared/lib-ts/context/context-selector.ts +524 -515
- package/dist/templates/_shared/lib-ts/context/context-store.ts +712 -668
- package/dist/templates/_shared/lib-ts/context/plan-manager.ts +312 -312
- package/dist/templates/_shared/lib-ts/context/task-tracker.ts +185 -185
- package/dist/templates/_shared/lib-ts/package.json +20 -20
- package/dist/templates/_shared/lib-ts/templates/formatters.ts +102 -102
- package/dist/templates/_shared/lib-ts/templates/plan-context.ts +58 -58
- package/dist/templates/_shared/lib-ts/tsconfig.json +13 -13
- package/dist/templates/_shared/lib-ts/types.ts +186 -180
- package/dist/templates/_shared/scripts/resolve_context.ts +33 -33
- package/dist/templates/_shared/scripts/status_line.ts +690 -690
- package/dist/templates/cc-native/.claude/commands/{rlm → cc-native/rlm}/ask.md +136 -136
- package/dist/templates/cc-native/.claude/commands/{rlm → cc-native/rlm}/index.md +21 -21
- package/dist/templates/cc-native/.claude/commands/{rlm → cc-native/rlm}/overview.md +56 -56
- package/dist/templates/cc-native/.claude/commands/cc-native/specdev.md +10 -10
- package/dist/templates/cc-native/.windsurf/workflows/cc-native/fix.md +8 -8
- package/dist/templates/cc-native/.windsurf/workflows/cc-native/implement.md +8 -8
- package/dist/templates/cc-native/.windsurf/workflows/cc-native/research.md +8 -8
- package/dist/templates/cc-native/CC-NATIVE-README.md +189 -189
- package/dist/templates/cc-native/TEMPLATE-SCHEMA.md +304 -304
- package/dist/templates/cc-native/_cc-native/agents/CLAUDE.md +143 -143
- package/dist/templates/cc-native/_cc-native/agents/PLAN-ORCHESTRATOR.md +213 -213
- package/dist/templates/cc-native/_cc-native/agents/plan-questions/PLAN-QUESTIONER.md +70 -70
- package/dist/templates/cc-native/_cc-native/cc-native.config.json +96 -96
- package/dist/templates/cc-native/_cc-native/hooks/CLAUDE.md +247 -247
- package/dist/templates/cc-native/_cc-native/hooks/cc-native-plan-review.ts +76 -76
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_subagent.ts +54 -54
- package/dist/templates/cc-native/_cc-native/hooks/enhance_plan_post_write.ts +51 -51
- package/dist/templates/cc-native/_cc-native/hooks/mark_questions_asked.ts +53 -53
- package/dist/templates/cc-native/_cc-native/hooks/plan_questions_early.ts +61 -61
- package/dist/templates/cc-native/_cc-native/lib-ts/agent-selection.ts +163 -163
- package/dist/templates/cc-native/_cc-native/lib-ts/aggregate-agents.ts +156 -156
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/format.ts +597 -597
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/index.ts +26 -26
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/tracker.ts +107 -107
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts/write.ts +119 -119
- package/dist/templates/cc-native/_cc-native/lib-ts/artifacts.ts +21 -21
- package/dist/templates/cc-native/_cc-native/lib-ts/cc-native-state.ts +319 -319
- package/dist/templates/cc-native/_cc-native/lib-ts/cli-output-parser.ts +144 -144
- package/dist/templates/cc-native/_cc-native/lib-ts/config.ts +57 -57
- package/dist/templates/cc-native/_cc-native/lib-ts/constants.ts +83 -83
- package/dist/templates/cc-native/_cc-native/lib-ts/corroboration.ts +119 -119
- package/dist/templates/cc-native/_cc-native/lib-ts/debug.ts +79 -79
- package/dist/templates/cc-native/_cc-native/lib-ts/graduation.ts +132 -132
- package/dist/templates/cc-native/_cc-native/lib-ts/index.ts +116 -116
- package/dist/templates/cc-native/_cc-native/lib-ts/json-parser.ts +168 -168
- package/dist/templates/cc-native/_cc-native/lib-ts/orchestrator.ts +70 -70
- package/dist/templates/cc-native/_cc-native/lib-ts/output-builder.ts +130 -130
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-discovery.ts +80 -80
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-enhancement.ts +41 -41
- package/dist/templates/cc-native/_cc-native/lib-ts/plan-questions.ts +101 -101
- package/dist/templates/cc-native/_cc-native/lib-ts/review-pipeline.ts +511 -511
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/agent.ts +71 -71
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/base/base-agent.ts +217 -217
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/index.ts +12 -12
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/claude-agent.ts +66 -65
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/codex-agent.ts +184 -184
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/gemini-agent.ts +39 -39
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/providers/orchestrator-claude-agent.ts +196 -195
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/schemas.ts +201 -201
- package/dist/templates/cc-native/_cc-native/lib-ts/reviewers/types.ts +21 -21
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/CLAUDE.md +480 -480
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/embedding-indexer.ts +287 -287
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/hyde.ts +148 -148
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/index.ts +54 -54
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/logger.ts +58 -58
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/ollama-client.ts +208 -208
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/retrieval-pipeline.ts +460 -460
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-indexer.ts +446 -447
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-loader.ts +280 -280
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/transcript-searcher.ts +274 -274
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/types.ts +201 -201
- package/dist/templates/cc-native/_cc-native/lib-ts/rlm/vector-store.ts +278 -278
- package/dist/templates/cc-native/_cc-native/lib-ts/settings.ts +184 -184
- package/dist/templates/cc-native/_cc-native/lib-ts/state.ts +275 -275
- package/dist/templates/cc-native/_cc-native/lib-ts/tsconfig.json +18 -18
- package/dist/templates/cc-native/_cc-native/lib-ts/types.ts +329 -329
- package/dist/templates/cc-native/_cc-native/lib-ts/verdict.ts +72 -72
- package/dist/templates/cc-native/_cc-native/workflows/specdev.md +9 -9
- package/oclif.manifest.json +1 -1
- package/package.json +108 -108
- package/dist/templates/cc-native/_cc-native/lib-ts/nul +0 -3
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HyDE (Hypothetical Document Embeddings) for improved RLM retrieval.
|
|
3
|
-
*
|
|
4
|
-
* Instead of embedding the user query directly, we:
|
|
5
|
-
* 1. Generate N hypothetical answers to the query
|
|
6
|
-
* 2. Embed each hypothetical answer
|
|
7
|
-
* 3. Average the embeddings
|
|
8
|
-
* 4. Search with the averaged embedding
|
|
9
|
-
*
|
|
10
|
-
* Research shows 20-45% recall improvement over direct query embedding.
|
|
11
|
-
* See: Gao et al., "Precise Zero-Shot Dense Retrieval without Relevance Labels" (ACL 2023)
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { generateText } from "./ollama-client.js";
|
|
15
|
-
import { embed, embedOne } from "./ollama-client.js";
|
|
16
|
-
import { logDebug, logInfo, logWarn } from "./logger.js";
|
|
17
|
-
|
|
18
|
-
const HOOK_NAME = "rlm_hyde";
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* System prompt for generating hypothetical responses.
|
|
22
|
-
*
|
|
23
|
-
* Key design choices:
|
|
24
|
-
* - Concrete example shows what "technical language" means (file names, function names)
|
|
25
|
-
* - Strict constraints (2-3 sentences, under 200 tokens) prevent rambling
|
|
26
|
-
* - Domain-specific priming ("past coding sessions")
|
|
27
|
-
* - Permission to speculate reduces "I don't know" refusals
|
|
28
|
-
* - Generic file paths (not RLM-specific) keep prompt reusable
|
|
29
|
-
*/
|
|
30
|
-
const HYDE_SYSTEM_PROMPT = `You are a knowledge base assistant. Given a user query about past coding sessions, generate a hypothetical answer that MIGHT exist in session transcripts.
|
|
31
|
-
|
|
32
|
-
Rules:
|
|
33
|
-
- Write 2-3 sentences maximum (under 200 tokens)
|
|
34
|
-
- Use specific technical language: file names, function names, error messages, tool names
|
|
35
|
-
- Describe actions taken, decisions made, or problems solved
|
|
36
|
-
- Do NOT say "I don't know" or ask clarifying questions
|
|
37
|
-
- Be concrete and specific, even if speculative
|
|
38
|
-
|
|
39
|
-
Example:
|
|
40
|
-
|
|
41
|
-
Query: "How did we fix the authentication redirect loop?"
|
|
42
|
-
|
|
43
|
-
Hypothetical Answer: "The redirect loop was caused by middleware checking session.user before the session was populated. We moved the auth check to a route-level guard in src/middleware/auth.ts and updated the session initialization order in app.ts to populate user data before routing."`;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Average multiple embedding vectors element-wise.
|
|
47
|
-
*
|
|
48
|
-
* Embedding vectors exist in semantic space where averaging is meaningful.
|
|
49
|
-
* Averaging across multiple hypothetical responses:
|
|
50
|
-
* - Preserves dimensionality (768-dim → 768-dim)
|
|
51
|
-
* - Smooths out noise/hallucinations from individual generations
|
|
52
|
-
* - Captures the "centroid" of the semantic space around the query
|
|
53
|
-
*/
|
|
54
|
-
function averageEmbeddings(embeddings: Float32Array[]): Float32Array {
|
|
55
|
-
if (embeddings.length === 0) {
|
|
56
|
-
throw new Error("No embeddings to average");
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
const dim = embeddings[0].length;
|
|
60
|
-
const avg = new Float32Array(dim);
|
|
61
|
-
|
|
62
|
-
// Sum all embeddings element-wise
|
|
63
|
-
for (const emb of embeddings) {
|
|
64
|
-
for (let i = 0; i < dim; i++) {
|
|
65
|
-
avg[i] += emb[i];
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Divide by count
|
|
70
|
-
const n = embeddings.length;
|
|
71
|
-
for (let i = 0; i < dim; i++) {
|
|
72
|
-
avg[i] /= n;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return avg;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Generate hypothetical responses to a query, embed them, and return the averaged embedding.
|
|
80
|
-
*
|
|
81
|
-
* Process:
|
|
82
|
-
* 1. Generate N hypothetical responses in parallel via Promise.all
|
|
83
|
-
* 2. Filter out failed/short responses (minimum 20 chars)
|
|
84
|
-
* 3. Require at least 3 successful responses (threshold for meaningful averaging)
|
|
85
|
-
* 4. Embed all successful responses in batch
|
|
86
|
-
* 5. Average the embeddings element-wise
|
|
87
|
-
*
|
|
88
|
-
* Fallback behavior:
|
|
89
|
-
* - If < 3 successful responses AND config.fallbackToQuery = true: return embedOne(query)
|
|
90
|
-
* - If < 3 successful responses AND config.fallbackToQuery = false: throw error
|
|
91
|
-
*
|
|
92
|
-
* @param query - The user's search query
|
|
93
|
-
* @param config - HyDE configuration (num responses, max tokens, timeout, fallback behavior)
|
|
94
|
-
* @returns Averaged embedding vector (Float32Array)
|
|
95
|
-
*/
|
|
96
|
-
export async function hydeQueryEmbedding(
|
|
97
|
-
query: string,
|
|
98
|
-
config: {
|
|
99
|
-
numResponses: number;
|
|
100
|
-
maxTokens: number;
|
|
101
|
-
timeout: number;
|
|
102
|
-
fallbackToQuery: boolean;
|
|
103
|
-
},
|
|
104
|
-
): Promise<Float32Array> {
|
|
105
|
-
logInfo(HOOK_NAME, `Generating ${config.numResponses} hypothetical responses via Ollama`);
|
|
106
|
-
|
|
107
|
-
// Step 1: Generate N hypothetical responses in parallel
|
|
108
|
-
const promises = Array.from({ length: config.numResponses }, (_, i) =>
|
|
109
|
-
generateText(query, {
|
|
110
|
-
systemPrompt: HYDE_SYSTEM_PROMPT,
|
|
111
|
-
maxTokens: config.maxTokens,
|
|
112
|
-
timeout: config.timeout,
|
|
113
|
-
temperature: 0.7, // Diversity across responses
|
|
114
|
-
}),
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
const results = await Promise.all(promises);
|
|
118
|
-
const responses = results
|
|
119
|
-
.filter((r) => r.success && r.text.trim().length > 20)
|
|
120
|
-
.map((r) => r.text.trim());
|
|
121
|
-
|
|
122
|
-
logDebug(HOOK_NAME, `Generated ${responses.length}/${config.numResponses} successful responses`);
|
|
123
|
-
|
|
124
|
-
// Step 2: Fallback if too few responses (minimum 3 for meaningful averaging)
|
|
125
|
-
if (responses.length < 3) {
|
|
126
|
-
logWarn(
|
|
127
|
-
HOOK_NAME,
|
|
128
|
-
`Only ${responses.length} responses generated (need ≥3), falling back to direct query embedding`,
|
|
129
|
-
);
|
|
130
|
-
if (config.fallbackToQuery) {
|
|
131
|
-
return embedOne(query);
|
|
132
|
-
}
|
|
133
|
-
throw new Error("HyDE generation failed: insufficient responses");
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Note: Proceeding with 3-4 responses when 1-2 fail is acceptable
|
|
137
|
-
// Averaging 3+ responses still provides HyDE benefits vs. direct query embedding
|
|
138
|
-
|
|
139
|
-
// Step 3: Embed all responses (batch for efficiency)
|
|
140
|
-
const embeddings = await embed(responses);
|
|
141
|
-
|
|
142
|
-
// Step 4: Average embeddings
|
|
143
|
-
logDebug(HOOK_NAME, `Averaging ${embeddings.length} embeddings`);
|
|
144
|
-
const avg = averageEmbeddings(embeddings);
|
|
145
|
-
|
|
146
|
-
logInfo(HOOK_NAME, `HyDE complete: ${responses.length} responses averaged`);
|
|
147
|
-
return avg;
|
|
148
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* HyDE (Hypothetical Document Embeddings) for improved RLM retrieval.
|
|
3
|
+
*
|
|
4
|
+
* Instead of embedding the user query directly, we:
|
|
5
|
+
* 1. Generate N hypothetical answers to the query
|
|
6
|
+
* 2. Embed each hypothetical answer
|
|
7
|
+
* 3. Average the embeddings
|
|
8
|
+
* 4. Search with the averaged embedding
|
|
9
|
+
*
|
|
10
|
+
* Research shows 20-45% recall improvement over direct query embedding.
|
|
11
|
+
* See: Gao et al., "Precise Zero-Shot Dense Retrieval without Relevance Labels" (ACL 2023)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { generateText } from "./ollama-client.js";
|
|
15
|
+
import { embed, embedOne } from "./ollama-client.js";
|
|
16
|
+
import { logDebug, logInfo, logWarn } from "./logger.js";
|
|
17
|
+
|
|
18
|
+
const HOOK_NAME = "rlm_hyde";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* System prompt for generating hypothetical responses.
|
|
22
|
+
*
|
|
23
|
+
* Key design choices:
|
|
24
|
+
* - Concrete example shows what "technical language" means (file names, function names)
|
|
25
|
+
* - Strict constraints (2-3 sentences, under 200 tokens) prevent rambling
|
|
26
|
+
* - Domain-specific priming ("past coding sessions")
|
|
27
|
+
* - Permission to speculate reduces "I don't know" refusals
|
|
28
|
+
* - Generic file paths (not RLM-specific) keep prompt reusable
|
|
29
|
+
*/
|
|
30
|
+
const HYDE_SYSTEM_PROMPT = `You are a knowledge base assistant. Given a user query about past coding sessions, generate a hypothetical answer that MIGHT exist in session transcripts.
|
|
31
|
+
|
|
32
|
+
Rules:
|
|
33
|
+
- Write 2-3 sentences maximum (under 200 tokens)
|
|
34
|
+
- Use specific technical language: file names, function names, error messages, tool names
|
|
35
|
+
- Describe actions taken, decisions made, or problems solved
|
|
36
|
+
- Do NOT say "I don't know" or ask clarifying questions
|
|
37
|
+
- Be concrete and specific, even if speculative
|
|
38
|
+
|
|
39
|
+
Example:
|
|
40
|
+
|
|
41
|
+
Query: "How did we fix the authentication redirect loop?"
|
|
42
|
+
|
|
43
|
+
Hypothetical Answer: "The redirect loop was caused by middleware checking session.user before the session was populated. We moved the auth check to a route-level guard in src/middleware/auth.ts and updated the session initialization order in app.ts to populate user data before routing."`;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Average multiple embedding vectors element-wise.
|
|
47
|
+
*
|
|
48
|
+
* Embedding vectors exist in semantic space where averaging is meaningful.
|
|
49
|
+
* Averaging across multiple hypothetical responses:
|
|
50
|
+
* - Preserves dimensionality (768-dim → 768-dim)
|
|
51
|
+
* - Smooths out noise/hallucinations from individual generations
|
|
52
|
+
* - Captures the "centroid" of the semantic space around the query
|
|
53
|
+
*/
|
|
54
|
+
function averageEmbeddings(embeddings: Float32Array[]): Float32Array {
|
|
55
|
+
if (embeddings.length === 0) {
|
|
56
|
+
throw new Error("No embeddings to average");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const dim = embeddings[0].length;
|
|
60
|
+
const avg = new Float32Array(dim);
|
|
61
|
+
|
|
62
|
+
// Sum all embeddings element-wise
|
|
63
|
+
for (const emb of embeddings) {
|
|
64
|
+
for (let i = 0; i < dim; i++) {
|
|
65
|
+
avg[i] += emb[i];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Divide by count
|
|
70
|
+
const n = embeddings.length;
|
|
71
|
+
for (let i = 0; i < dim; i++) {
|
|
72
|
+
avg[i] /= n;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return avg;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Generate hypothetical responses to a query, embed them, and return the averaged embedding.
|
|
80
|
+
*
|
|
81
|
+
* Process:
|
|
82
|
+
* 1. Generate N hypothetical responses in parallel via Promise.all
|
|
83
|
+
* 2. Filter out failed/short responses (minimum 20 chars)
|
|
84
|
+
* 3. Require at least 3 successful responses (threshold for meaningful averaging)
|
|
85
|
+
* 4. Embed all successful responses in batch
|
|
86
|
+
* 5. Average the embeddings element-wise
|
|
87
|
+
*
|
|
88
|
+
* Fallback behavior:
|
|
89
|
+
* - If < 3 successful responses AND config.fallbackToQuery = true: return embedOne(query)
|
|
90
|
+
* - If < 3 successful responses AND config.fallbackToQuery = false: throw error
|
|
91
|
+
*
|
|
92
|
+
* @param query - The user's search query
|
|
93
|
+
* @param config - HyDE configuration (num responses, max tokens, timeout, fallback behavior)
|
|
94
|
+
* @returns Averaged embedding vector (Float32Array)
|
|
95
|
+
*/
|
|
96
|
+
export async function hydeQueryEmbedding(
|
|
97
|
+
query: string,
|
|
98
|
+
config: {
|
|
99
|
+
numResponses: number;
|
|
100
|
+
maxTokens: number;
|
|
101
|
+
timeout: number;
|
|
102
|
+
fallbackToQuery: boolean;
|
|
103
|
+
},
|
|
104
|
+
): Promise<Float32Array> {
|
|
105
|
+
logInfo(HOOK_NAME, `Generating ${config.numResponses} hypothetical responses via Ollama`);
|
|
106
|
+
|
|
107
|
+
// Step 1: Generate N hypothetical responses in parallel
|
|
108
|
+
const promises = Array.from({ length: config.numResponses }, (_, i) =>
|
|
109
|
+
generateText(query, {
|
|
110
|
+
systemPrompt: HYDE_SYSTEM_PROMPT,
|
|
111
|
+
maxTokens: config.maxTokens,
|
|
112
|
+
timeout: config.timeout,
|
|
113
|
+
temperature: 0.7, // Diversity across responses
|
|
114
|
+
}),
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
const results = await Promise.all(promises);
|
|
118
|
+
const responses = results
|
|
119
|
+
.filter((r) => r.success && r.text.trim().length > 20)
|
|
120
|
+
.map((r) => r.text.trim());
|
|
121
|
+
|
|
122
|
+
logDebug(HOOK_NAME, `Generated ${responses.length}/${config.numResponses} successful responses`);
|
|
123
|
+
|
|
124
|
+
// Step 2: Fallback if too few responses (minimum 3 for meaningful averaging)
|
|
125
|
+
if (responses.length < 3) {
|
|
126
|
+
logWarn(
|
|
127
|
+
HOOK_NAME,
|
|
128
|
+
`Only ${responses.length} responses generated (need ≥3), falling back to direct query embedding`,
|
|
129
|
+
);
|
|
130
|
+
if (config.fallbackToQuery) {
|
|
131
|
+
return embedOne(query);
|
|
132
|
+
}
|
|
133
|
+
throw new Error("HyDE generation failed: insufficient responses");
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Note: Proceeding with 3-4 responses when 1-2 fail is acceptable
|
|
137
|
+
// Averaging 3+ responses still provides HyDE benefits vs. direct query embedding
|
|
138
|
+
|
|
139
|
+
// Step 3: Embed all responses (batch for efficiency)
|
|
140
|
+
const embeddings = await embed(responses);
|
|
141
|
+
|
|
142
|
+
// Step 4: Average embeddings
|
|
143
|
+
logDebug(HOOK_NAME, `Averaging ${embeddings.length} embeddings`);
|
|
144
|
+
const avg = averageEmbeddings(embeddings);
|
|
145
|
+
|
|
146
|
+
logInfo(HOOK_NAME, `HyDE complete: ${responses.length} responses averaged`);
|
|
147
|
+
return avg;
|
|
148
|
+
}
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RLM — Recursive Language Model session transcript memory.
|
|
3
|
-
*
|
|
4
|
-
* Public API re-exports for programmatic use from hooks/agents.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
export {
|
|
8
|
-
CURRENT_SCHEMA_VERSION,
|
|
9
|
-
CLAUDE_PROJECTS_DIR,
|
|
10
|
-
RLM_INDEX_DIR,
|
|
11
|
-
RLM_VECTOR_DB_PATH,
|
|
12
|
-
OLLAMA_BASE_URL,
|
|
13
|
-
OLLAMA_EMBED_MODEL,
|
|
14
|
-
EMBED_DIMENSIONS,
|
|
15
|
-
VECTOR_TOP_K,
|
|
16
|
-
MAX_LOADER_CHARS,
|
|
17
|
-
MAX_PARALLEL_SUMMARIZERS,
|
|
18
|
-
TOP_N_HEAP,
|
|
19
|
-
WEIGHT,
|
|
20
|
-
type SessionIndex,
|
|
21
|
-
type SearchResult,
|
|
22
|
-
type LoadedSegment,
|
|
23
|
-
type IndexSegment,
|
|
24
|
-
type VectorSearchResult,
|
|
25
|
-
type ChunkSummary,
|
|
26
|
-
type RankedSession,
|
|
27
|
-
type RetrievalResult,
|
|
28
|
-
} from "./types.js";
|
|
29
|
-
|
|
30
|
-
export {
|
|
31
|
-
discoverSessions,
|
|
32
|
-
indexSession,
|
|
33
|
-
writeIndex,
|
|
34
|
-
needsIndexing,
|
|
35
|
-
runBatch,
|
|
36
|
-
} from "./transcript-indexer.js";
|
|
37
|
-
|
|
38
|
-
export { search, scoreIndex, tokenize, type SearchOptions } from "./transcript-searcher.js";
|
|
39
|
-
|
|
40
|
-
export { loadTranscript } from "./transcript-loader.js";
|
|
41
|
-
|
|
42
|
-
export { checkOllamaHealth, embed, embedOne, type OllamaConfig } from "./ollama-client.js";
|
|
43
|
-
|
|
44
|
-
export {
|
|
45
|
-
openVectorDb,
|
|
46
|
-
insertChunks,
|
|
47
|
-
markSessionEmbedded,
|
|
48
|
-
isSessionEmbedded,
|
|
49
|
-
deleteSessionChunks,
|
|
50
|
-
searchKnn,
|
|
51
|
-
getStats,
|
|
52
|
-
type ChunkRow,
|
|
53
|
-
type VectorStats,
|
|
54
|
-
} from "./vector-store.js";
|
|
1
|
+
/**
|
|
2
|
+
* RLM — Recursive Language Model session transcript memory.
|
|
3
|
+
*
|
|
4
|
+
* Public API re-exports for programmatic use from hooks/agents.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
CURRENT_SCHEMA_VERSION,
|
|
9
|
+
CLAUDE_PROJECTS_DIR,
|
|
10
|
+
RLM_INDEX_DIR,
|
|
11
|
+
RLM_VECTOR_DB_PATH,
|
|
12
|
+
OLLAMA_BASE_URL,
|
|
13
|
+
OLLAMA_EMBED_MODEL,
|
|
14
|
+
EMBED_DIMENSIONS,
|
|
15
|
+
VECTOR_TOP_K,
|
|
16
|
+
MAX_LOADER_CHARS,
|
|
17
|
+
MAX_PARALLEL_SUMMARIZERS,
|
|
18
|
+
TOP_N_HEAP,
|
|
19
|
+
WEIGHT,
|
|
20
|
+
type SessionIndex,
|
|
21
|
+
type SearchResult,
|
|
22
|
+
type LoadedSegment,
|
|
23
|
+
type IndexSegment,
|
|
24
|
+
type VectorSearchResult,
|
|
25
|
+
type ChunkSummary,
|
|
26
|
+
type RankedSession,
|
|
27
|
+
type RetrievalResult,
|
|
28
|
+
} from "./types.js";
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
discoverSessions,
|
|
32
|
+
indexSession,
|
|
33
|
+
writeIndex,
|
|
34
|
+
needsIndexing,
|
|
35
|
+
runBatch,
|
|
36
|
+
} from "./transcript-indexer.js";
|
|
37
|
+
|
|
38
|
+
export { search, scoreIndex, tokenize, type SearchOptions } from "./transcript-searcher.js";
|
|
39
|
+
|
|
40
|
+
export { loadTranscript } from "./transcript-loader.js";
|
|
41
|
+
|
|
42
|
+
export { checkOllamaHealth, embed, embedOne, type OllamaConfig } from "./ollama-client.js";
|
|
43
|
+
|
|
44
|
+
export {
|
|
45
|
+
openVectorDb,
|
|
46
|
+
insertChunks,
|
|
47
|
+
markSessionEmbedded,
|
|
48
|
+
isSessionEmbedded,
|
|
49
|
+
deleteSessionChunks,
|
|
50
|
+
searchKnn,
|
|
51
|
+
getStats,
|
|
52
|
+
type ChunkRow,
|
|
53
|
+
type VectorStats,
|
|
54
|
+
} from "./vector-store.js";
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Re-export shared logger for RLM tools.
|
|
3
|
-
*
|
|
4
|
-
* When RLM tools run as standalone CLI scripts (bun transcript-indexer.ts),
|
|
5
|
-
* bun's module resolution uses lib-ts/package.json as the package boundary.
|
|
6
|
-
* Relative imports that cross this boundary fail. This re-export bridges the gap
|
|
7
|
-
* by importing at build time (when the full tsconfig include paths are resolved)
|
|
8
|
-
* and re-exporting for runtime use.
|
|
9
|
-
*
|
|
10
|
-
* For standalone CLI execution, we inline a minimal fallback logger that writes
|
|
11
|
-
* to stderr (same format as the shared logger's stderr mode).
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
let logInfo: (hookName: string, message: string, opts?: Record<string, unknown>) => void;
|
|
15
|
-
let logWarn: (hookName: string, message: string, opts?: Record<string, unknown>) => void;
|
|
16
|
-
let logError: (hookName: string, message: string, opts?: Record<string, unknown>) => void;
|
|
17
|
-
let logDebug: (hookName: string, message: string, opts?: Record<string, unknown>) => void;
|
|
18
|
-
|
|
19
|
-
try {
|
|
20
|
-
// Try shared logger (works when imported as part of the hook pipeline)
|
|
21
|
-
const mod = await import("../../../../_shared/lib-ts/base/logger.js");
|
|
22
|
-
logInfo = mod.logInfo;
|
|
23
|
-
logWarn = mod.logWarn;
|
|
24
|
-
logError = mod.logError;
|
|
25
|
-
logDebug = mod.logDebug;
|
|
26
|
-
} catch {
|
|
27
|
-
// Fallback: minimal stderr+file logger for standalone CLI execution
|
|
28
|
-
const fallback = (level: string) => {
|
|
29
|
-
return (hookName: string, message: string, opts?: Record<string, unknown>) => {
|
|
30
|
-
const shouldStderr = opts?.stderr === true || level === "error";
|
|
31
|
-
if (shouldStderr) {
|
|
32
|
-
process.stderr.write(`[${hookName}] ${message}\n`);
|
|
33
|
-
}
|
|
34
|
-
// Also try JSONL file logging
|
|
35
|
-
try {
|
|
36
|
-
const fs = require("fs");
|
|
37
|
-
const path = require("path");
|
|
38
|
-
const logDir = path.join(process.cwd(), "_output");
|
|
39
|
-
fs.mkdirSync(logDir, { recursive: true });
|
|
40
|
-
const entry = JSON.stringify({
|
|
41
|
-
ts: new Date().toISOString(),
|
|
42
|
-
level,
|
|
43
|
-
hook: hookName,
|
|
44
|
-
msg: message,
|
|
45
|
-
});
|
|
46
|
-
fs.appendFileSync(path.join(logDir, "hook-log.jsonl"), entry + "\n");
|
|
47
|
-
} catch {
|
|
48
|
-
// Never crash on logging failure
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
};
|
|
52
|
-
logInfo = fallback("info");
|
|
53
|
-
logWarn = fallback("warn");
|
|
54
|
-
logError = fallback("error");
|
|
55
|
-
logDebug = fallback("debug");
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export { logInfo, logWarn, logError, logDebug };
|
|
1
|
+
/**
|
|
2
|
+
* Re-export shared logger for RLM tools.
|
|
3
|
+
*
|
|
4
|
+
* When RLM tools run as standalone CLI scripts (bun transcript-indexer.ts),
|
|
5
|
+
* bun's module resolution uses lib-ts/package.json as the package boundary.
|
|
6
|
+
* Relative imports that cross this boundary fail. This re-export bridges the gap
|
|
7
|
+
* by importing at build time (when the full tsconfig include paths are resolved)
|
|
8
|
+
* and re-exporting for runtime use.
|
|
9
|
+
*
|
|
10
|
+
* For standalone CLI execution, we inline a minimal fallback logger that writes
|
|
11
|
+
* to stderr (same format as the shared logger's stderr mode).
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
let logInfo: (hookName: string, message: string, opts?: Record<string, unknown>) => void;
|
|
15
|
+
let logWarn: (hookName: string, message: string, opts?: Record<string, unknown>) => void;
|
|
16
|
+
let logError: (hookName: string, message: string, opts?: Record<string, unknown>) => void;
|
|
17
|
+
let logDebug: (hookName: string, message: string, opts?: Record<string, unknown>) => void;
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
// Try shared logger (works when imported as part of the hook pipeline)
|
|
21
|
+
const mod = await import("../../../../_shared/lib-ts/base/logger.js");
|
|
22
|
+
logInfo = mod.logInfo;
|
|
23
|
+
logWarn = mod.logWarn;
|
|
24
|
+
logError = mod.logError;
|
|
25
|
+
logDebug = mod.logDebug;
|
|
26
|
+
} catch {
|
|
27
|
+
// Fallback: minimal stderr+file logger for standalone CLI execution
|
|
28
|
+
const fallback = (level: string) => {
|
|
29
|
+
return (hookName: string, message: string, opts?: Record<string, unknown>) => {
|
|
30
|
+
const shouldStderr = opts?.stderr === true || level === "error";
|
|
31
|
+
if (shouldStderr) {
|
|
32
|
+
process.stderr.write(`[${hookName}] ${message}\n`);
|
|
33
|
+
}
|
|
34
|
+
// Also try JSONL file logging
|
|
35
|
+
try {
|
|
36
|
+
const fs = require("fs");
|
|
37
|
+
const path = require("path");
|
|
38
|
+
const logDir = path.join(process.cwd(), "_output");
|
|
39
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
40
|
+
const entry = JSON.stringify({
|
|
41
|
+
ts: new Date().toISOString(),
|
|
42
|
+
level,
|
|
43
|
+
hook: hookName,
|
|
44
|
+
msg: message,
|
|
45
|
+
});
|
|
46
|
+
fs.appendFileSync(path.join(logDir, "hook-log.jsonl"), entry + "\n");
|
|
47
|
+
} catch {
|
|
48
|
+
// Never crash on logging failure
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
logInfo = fallback("info");
|
|
53
|
+
logWarn = fallback("warn");
|
|
54
|
+
logError = fallback("error");
|
|
55
|
+
logDebug = fallback("debug");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { logInfo, logWarn, logError, logDebug };
|