capman 0.5.5 → 0.6.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.
- package/CHANGELOG.md +1 -1
- package/bin/lib/cmd-generate.js +156 -12
- package/bin/lib/cmd-help.js +3 -0
- package/dist/cjs/engine.d.ts +53 -1
- package/dist/cjs/engine.d.ts.map +1 -1
- package/dist/cjs/engine.js +219 -9
- package/dist/cjs/engine.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/learning.d.ts.map +1 -1
- package/dist/cjs/learning.js +12 -18
- package/dist/cjs/learning.js.map +1 -1
- package/dist/cjs/matcher.d.ts +55 -0
- package/dist/cjs/matcher.d.ts.map +1 -1
- package/dist/cjs/matcher.js +267 -31
- package/dist/cjs/matcher.js.map +1 -1
- package/dist/cjs/schema.d.ts +46 -28
- package/dist/cjs/schema.d.ts.map +1 -1
- package/dist/cjs/schema.js +1 -0
- package/dist/cjs/schema.js.map +1 -1
- package/dist/cjs/types.d.ts +7 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/engine.d.ts +53 -1
- package/dist/esm/engine.js +220 -10
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/learning.js +13 -19
- package/dist/esm/matcher.d.ts +55 -0
- package/dist/esm/matcher.js +261 -31
- package/dist/esm/schema.d.ts +46 -28
- package/dist/esm/schema.js +1 -0
- package/dist/esm/types.d.ts +7 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/bin/lib/cmd-generate.js
CHANGED
|
@@ -66,9 +66,38 @@ Rules:
|
|
|
66
66
|
- Respond ONLY with the raw JSON object — no markdown, no explanation`
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
// ─── Example enrichment ───────────────────────────────────────────────────────
|
|
70
|
+
|
|
71
|
+
function buildEnrichPrompt(capabilities) {
|
|
72
|
+
const caps = capabilities
|
|
73
|
+
.filter(c => (c.examples?.length ?? 0) < 20)
|
|
74
|
+
.map(c => ({
|
|
75
|
+
id: c.id,
|
|
76
|
+
name: c.name,
|
|
77
|
+
desc: c.description,
|
|
78
|
+
existing: c.examples ?? [],
|
|
79
|
+
}))
|
|
80
|
+
|
|
81
|
+
if (caps.length === 0) return null
|
|
82
|
+
|
|
83
|
+
return `You are helping improve an AI agent capability manifest.
|
|
84
|
+
For each capability below, generate 20 natural language phrasings a user might say to invoke it.
|
|
85
|
+
Phrasings must be DIFFERENT from the existing examples listed.
|
|
86
|
+
Return ONLY a JSON object mapping capability id to an array of new phrasings. No explanation.
|
|
87
|
+
|
|
88
|
+
Capabilities:
|
|
89
|
+
${JSON.stringify(caps, null, 2)}
|
|
90
|
+
|
|
91
|
+
Respond with ONLY this structure:
|
|
92
|
+
{
|
|
93
|
+
"<capability_id>": ["phrasing 1", "phrasing 2", ...],
|
|
94
|
+
...
|
|
95
|
+
}`
|
|
96
|
+
}
|
|
97
|
+
|
|
69
98
|
// ─── LLM caller ───────────────────────────────────────────────────────────────
|
|
70
99
|
|
|
71
|
-
async function callLLM(provider, apiKey, prompt) {
|
|
100
|
+
async function callLLM(provider, apiKey, prompt, maxTokens) {
|
|
72
101
|
if (provider === 'anthropic') {
|
|
73
102
|
const res = await fetch('https://api.anthropic.com/v1/messages', {
|
|
74
103
|
method: 'POST',
|
|
@@ -79,7 +108,7 @@ async function callLLM(provider, apiKey, prompt) {
|
|
|
79
108
|
},
|
|
80
109
|
body: JSON.stringify({
|
|
81
110
|
model: 'claude-sonnet-4-20250514',
|
|
82
|
-
max_tokens: 4000,
|
|
111
|
+
max_tokens: maxTokens ?? 4000,
|
|
83
112
|
messages: [{ role: 'user', content: prompt }],
|
|
84
113
|
}),
|
|
85
114
|
})
|
|
@@ -92,6 +121,28 @@ async function callLLM(provider, apiKey, prompt) {
|
|
|
92
121
|
return JSON.parse(text).content[0].text
|
|
93
122
|
}
|
|
94
123
|
|
|
124
|
+
if (provider === 'groq') {
|
|
125
|
+
const res = await fetch('https://api.groq.com/openai/v1/chat/completions', {
|
|
126
|
+
method: 'POST',
|
|
127
|
+
headers: {
|
|
128
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
129
|
+
'Content-Type': 'application/json',
|
|
130
|
+
},
|
|
131
|
+
body: JSON.stringify({
|
|
132
|
+
model: 'llama-3.3-70b-versatile',
|
|
133
|
+
max_tokens: maxTokens ?? 4096,
|
|
134
|
+
messages: [{ role: 'user', content: prompt }],
|
|
135
|
+
}),
|
|
136
|
+
})
|
|
137
|
+
const text = await res.text()
|
|
138
|
+
if (!res.ok) {
|
|
139
|
+
let msg = res.statusText
|
|
140
|
+
try { msg = JSON.parse(text).error?.message ?? msg } catch {}
|
|
141
|
+
throw new Error(`Groq API error: ${msg}`)
|
|
142
|
+
}
|
|
143
|
+
return JSON.parse(text).choices[0].message.content
|
|
144
|
+
}
|
|
145
|
+
|
|
95
146
|
if (provider === 'openai') {
|
|
96
147
|
const res = await fetch('https://api.openai.com/v1/chat/completions', {
|
|
97
148
|
method: 'POST',
|
|
@@ -101,7 +152,7 @@ async function callLLM(provider, apiKey, prompt) {
|
|
|
101
152
|
},
|
|
102
153
|
body: JSON.stringify({
|
|
103
154
|
model: 'gpt-4o-mini',
|
|
104
|
-
max_tokens: 4000,
|
|
155
|
+
max_tokens: maxTokens ?? 4000,
|
|
105
156
|
messages: [{ role: 'user', content: prompt }],
|
|
106
157
|
}),
|
|
107
158
|
})
|
|
@@ -124,7 +175,7 @@ async function callLLM(provider, apiKey, prompt) {
|
|
|
124
175
|
},
|
|
125
176
|
body: JSON.stringify({
|
|
126
177
|
model: 'openai/gpt-oss-120b:free',
|
|
127
|
-
max_tokens: 4000,
|
|
178
|
+
max_tokens: maxTokens ?? 4000,
|
|
128
179
|
messages: [{ role: 'user', content: prompt }],
|
|
129
180
|
provider: { order: ['open-inference'], allow_fallbacks: true },
|
|
130
181
|
}),
|
|
@@ -141,14 +192,70 @@ async function callLLM(provider, apiKey, prompt) {
|
|
|
141
192
|
throw new Error(`Unknown provider: ${provider}`)
|
|
142
193
|
}
|
|
143
194
|
|
|
195
|
+
async function enrichExamples(config, apiKey, provider) {
|
|
196
|
+
const prompt = buildEnrichPrompt(config.capabilities)
|
|
197
|
+
if (!prompt) {
|
|
198
|
+
log.info('All capabilities already have ≥ 20 examples — nothing to enrich')
|
|
199
|
+
return config
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
log.info(`Enriching examples for ${config.capabilities.filter(c => (c.examples?.length ?? 0) < 20).length} capabilities...`)
|
|
203
|
+
|
|
204
|
+
let raw
|
|
205
|
+
try {
|
|
206
|
+
raw = await callLLM(provider, apiKey, prompt, 4096)
|
|
207
|
+
} catch (e) {
|
|
208
|
+
log.warn(`LLM call failed during enrichment: ${e.message}`)
|
|
209
|
+
return config
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
let parsed
|
|
213
|
+
try {
|
|
214
|
+
// Strip any markdown code fences, then try direct parse.
|
|
215
|
+
// If that fails, extract the first top-level {...} block (handles preamble/postamble).
|
|
216
|
+
const stripped = raw.replace(/```[\w]*\n?/g, '').trim()
|
|
217
|
+
let jsonStr = stripped
|
|
218
|
+
if (!jsonStr.startsWith('{')) {
|
|
219
|
+
const start = stripped.indexOf('{')
|
|
220
|
+
const end = stripped.lastIndexOf('}')
|
|
221
|
+
if (start !== -1 && end !== -1 && end > start) jsonStr = stripped.slice(start, end + 1)
|
|
222
|
+
}
|
|
223
|
+
parsed = JSON.parse(jsonStr)
|
|
224
|
+
} catch {
|
|
225
|
+
log.warn('Could not parse LLM enrichment response — skipping enrichment')
|
|
226
|
+
return config
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
let totalAdded = 0
|
|
230
|
+
const enrichedCapabilities = config.capabilities.map(cap => {
|
|
231
|
+
const newPhrasings = parsed[cap.id]
|
|
232
|
+
if (!Array.isArray(newPhrasings) || newPhrasings.length === 0) return cap
|
|
233
|
+
|
|
234
|
+
const existing = new Set((cap.examples ?? []).map(e => e.toLowerCase().trim()))
|
|
235
|
+
const unique = newPhrasings
|
|
236
|
+
.filter(p => typeof p === 'string' && p.trim().length > 0)
|
|
237
|
+
.filter(p => !existing.has(p.toLowerCase().trim()))
|
|
238
|
+
.slice(0, 20)
|
|
239
|
+
|
|
240
|
+
if (unique.length === 0) return cap
|
|
241
|
+
|
|
242
|
+
totalAdded += unique.length
|
|
243
|
+
return { ...cap, examples: [...(cap.examples ?? []), ...unique] }
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
log.success(`Added ${totalAdded} new phrasings across ${config.capabilities.length} capabilities`)
|
|
247
|
+
return { ...config, capabilities: enrichedCapabilities }
|
|
248
|
+
}
|
|
249
|
+
|
|
144
250
|
// ─── Command ──────────────────────────────────────────────────────────────────
|
|
145
251
|
|
|
146
252
|
module.exports = async function cmdGenerate() {
|
|
147
253
|
header()
|
|
148
254
|
const { generate, loadConfig, writeManifest, validate, parseOpenAPI } = requireSrc()
|
|
149
255
|
|
|
150
|
-
const fromFlag
|
|
151
|
-
const aiFlag
|
|
256
|
+
const fromFlag = getFlag('--from')
|
|
257
|
+
const aiFlag = flags.includes('--ai')
|
|
258
|
+
const enrichFlag = flags.includes('--enrich-examples')
|
|
152
259
|
const cwd = process.cwd()
|
|
153
260
|
const outPath = safeOutputPath(getFlag('--out') ?? 'manifest.json', cwd)
|
|
154
261
|
const configOut = safeOutputPath(getFlag('--config-out') ?? 'capman.config.js', cwd)
|
|
@@ -165,7 +272,7 @@ const fromFlag = getFlag('--from')
|
|
|
165
272
|
process.exit(1)
|
|
166
273
|
}
|
|
167
274
|
|
|
168
|
-
|
|
275
|
+
let { config, stats } = result
|
|
169
276
|
|
|
170
277
|
log.success(`Parsed ${stats.total} capabilities from spec`)
|
|
171
278
|
if (stats.skipped > 0) log.info(`Skipped ${stats.skipped} operations (insufficient info)`)
|
|
@@ -177,7 +284,19 @@ const fromFlag = getFlag('--from')
|
|
|
177
284
|
module.exports = ${JSON.stringify(config, null, 2)}
|
|
178
285
|
`
|
|
179
286
|
fs.writeFileSync(configOut, configContent)
|
|
180
|
-
|
|
287
|
+
// Enrich examples if requested
|
|
288
|
+
if (enrichFlag) {
|
|
289
|
+
const apiKey = process.env.ANTHROPIC_API_KEY?.trim() || process.env.GROQ_API_KEY?.trim() || process.env.OPENAI_API_KEY?.trim() || process.env.OPENROUTER_API_KEY?.trim() || null
|
|
290
|
+
const provider = process.env.ANTHROPIC_API_KEY?.trim() ? 'anthropic' : process.env.GROQ_API_KEY?.trim() ? 'groq' : process.env.OPENAI_API_KEY?.trim() ? 'openai' : process.env.OPENROUTER_API_KEY?.trim() ? 'openrouter' : null
|
|
291
|
+
if (!apiKey || !provider) {
|
|
292
|
+
log.warn('--enrich-examples requires an LLM API key — skipping enrichment')
|
|
293
|
+
} else {
|
|
294
|
+
config = await enrichExamples(config, apiKey, provider)
|
|
295
|
+
fs.writeFileSync(configOut, `// Auto-generated by capman from OpenAPI spec\n// Review and adjust before committing\n\nmodule.exports = ${JSON.stringify(config, null, 2)}\n`)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
log.success(`Config written to ${configOut}`)
|
|
181
300
|
|
|
182
301
|
try {
|
|
183
302
|
const manifest = generate(config)
|
|
@@ -192,7 +311,8 @@ const fromFlag = getFlag('--from')
|
|
|
192
311
|
console.log(` ${c.gray}Next steps:${c.reset}`)
|
|
193
312
|
console.log(` 1. Review ${c.teal}${configOut}${c.reset} — adjust descriptions and examples`)
|
|
194
313
|
console.log(` 2. Run ${c.teal}npx capman validate${c.reset} to check your manifest`)
|
|
195
|
-
console.log(` 3. Run ${c.teal}npx capman
|
|
314
|
+
console.log(` 3. Run ${c.teal}npx capman generate --enrich-examples${c.reset} to add phrasings ${c.gray}(better matching)${c.reset}`)
|
|
315
|
+
console.log(` 4. Run ${c.teal}npx capman demo${c.reset} to see it in action`)
|
|
196
316
|
console.log()
|
|
197
317
|
return
|
|
198
318
|
}
|
|
@@ -220,17 +340,19 @@ const fromFlag = getFlag('--from')
|
|
|
220
340
|
|
|
221
341
|
const apiKey =
|
|
222
342
|
process.env.ANTHROPIC_API_KEY?.trim() ||
|
|
343
|
+
process.env.GROQ_API_KEY?.trim() ||
|
|
223
344
|
process.env.OPENAI_API_KEY?.trim() ||
|
|
224
345
|
process.env.OPENROUTER_API_KEY?.trim() ||
|
|
225
346
|
null
|
|
226
347
|
const provider =
|
|
227
348
|
process.env.ANTHROPIC_API_KEY?.trim() ? 'anthropic' :
|
|
349
|
+
process.env.GROQ_API_KEY?.trim() ? 'groq' :
|
|
228
350
|
process.env.OPENAI_API_KEY?.trim() ? 'openai' :
|
|
229
351
|
process.env.OPENROUTER_API_KEY?.trim() ? 'openrouter' : null
|
|
230
352
|
|
|
231
353
|
if (!apiKey || !provider) {
|
|
232
354
|
log.error('No LLM API key found.')
|
|
233
|
-
console.log(` Set one of: ${c.teal}ANTHROPIC_API_KEY${c.reset}, ${c.teal}OPENAI_API_KEY${c.reset}, or ${c.teal}OPENROUTER_API_KEY${c.reset}`)
|
|
355
|
+
console.log(` Set one of: ${c.teal}ANTHROPIC_API_KEY${c.reset},${c.teal}GROQ_API_KEY${c.reset}, ${c.teal}OPENAI_API_KEY${c.reset}, or ${c.teal}OPENROUTER_API_KEY${c.reset}`)
|
|
234
356
|
process.exit(1)
|
|
235
357
|
}
|
|
236
358
|
|
|
@@ -255,6 +377,11 @@ const fromFlag = getFlag('--from')
|
|
|
255
377
|
process.exit(1)
|
|
256
378
|
}
|
|
257
379
|
|
|
380
|
+
// Enrich examples if requested
|
|
381
|
+
if (enrichFlag) {
|
|
382
|
+
config = await enrichExamples(config, apiKey, provider)
|
|
383
|
+
}
|
|
384
|
+
|
|
258
385
|
const configContent = `// Auto-generated by capman AI\n// Review before committing\n\nmodule.exports = ${JSON.stringify(config, null, 2)}\n`
|
|
259
386
|
fs.writeFileSync(configOut, configContent)
|
|
260
387
|
log.success(`Config written to ${configOut}`)
|
|
@@ -270,8 +397,9 @@ const fromFlag = getFlag('--from')
|
|
|
270
397
|
|
|
271
398
|
console.log()
|
|
272
399
|
console.log(` ${c.gray}Review ${configOut} — the AI may have missed things.${c.reset}`)
|
|
273
|
-
console.log(` ${c.teal}npx capman validate${c.reset}
|
|
274
|
-
console.log(` ${c.teal}npx capman inspect${c.reset}
|
|
400
|
+
console.log(` ${c.teal}npx capman validate${c.reset} ${c.gray}→ check for errors${c.reset}`)
|
|
401
|
+
console.log(` ${c.teal}npx capman inspect${c.reset} ${c.gray}→ see all capabilities${c.reset}`)
|
|
402
|
+
console.log(` ${c.teal}npx capman generate --enrich-examples${c.reset} ${c.gray}→ add 20 phrasings per capability (better matching)${c.reset}`)
|
|
275
403
|
console.log()
|
|
276
404
|
return
|
|
277
405
|
}
|
|
@@ -306,6 +434,22 @@ const fromFlag = getFlag('--from')
|
|
|
306
434
|
validation.warnings.forEach(w => log.warn(w))
|
|
307
435
|
}
|
|
308
436
|
|
|
437
|
+
// Enrich examples if requested
|
|
438
|
+
if (enrichFlag) {
|
|
439
|
+
const apiKey = process.env.ANTHROPIC_API_KEY?.trim() || process.env.GROQ_API_KEY?.trim() || process.env.OPENAI_API_KEY?.trim() || process.env.OPENROUTER_API_KEY?.trim() || null
|
|
440
|
+
const provider = process.env.ANTHROPIC_API_KEY?.trim() ? 'anthropic' : process.env.GROQ_API_KEY?.trim() ? 'groq' : process.env.OPENAI_API_KEY?.trim() ? 'openai' : process.env.OPENROUTER_API_KEY?.trim() ? 'openrouter' : null
|
|
441
|
+
if (!apiKey || !provider) {
|
|
442
|
+
log.warn('--enrich-examples requires an LLM API key — skipping enrichment')
|
|
443
|
+
} else {
|
|
444
|
+
const enriched = await enrichExamples(config, apiKey, provider)
|
|
445
|
+
if (enriched !== config) {
|
|
446
|
+
const configPath2 = getFlag('--config-out') ?? 'capman.config.js'
|
|
447
|
+
fs.writeFileSync(safeOutputPath(configPath2, cwd), `// Enriched by capman --enrich-examples\n\nmodule.exports = ${JSON.stringify(enriched, null, 2)}\n`)
|
|
448
|
+
manifest = generate(enriched)
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
309
453
|
writeManifest(manifest, outPath)
|
|
310
454
|
log.success(`Manifest written to ${outPath}`)
|
|
311
455
|
log.info(`${manifest.capabilities.length} capabilities registered`)
|
package/bin/lib/cmd-help.js
CHANGED
|
@@ -12,6 +12,7 @@ module.exports = function cmdHelp() {
|
|
|
12
12
|
console.log(` ${c.teal}generate --from <path|url>${c.reset} Generate from OpenAPI/Swagger spec`)
|
|
13
13
|
console.log(` ${c.teal}generate --ai${c.reset} Generate manifest using AI`)
|
|
14
14
|
console.log(` ${c.teal}validate${c.reset} Validate an existing manifest.json`)
|
|
15
|
+
console.log(` ${c.teal}generate --enrich-examples${c.reset} Add 20 phrasings per capability via LLM`)
|
|
15
16
|
console.log(` ${c.teal}inspect${c.reset} Print all capabilities in manifest`)
|
|
16
17
|
console.log(` ${c.teal}demo${c.reset} Run a live demo with sample queries`)
|
|
17
18
|
console.log(` ${c.teal}run "query"${c.reset} Run a query against your manifest`)
|
|
@@ -22,5 +23,7 @@ module.exports = function cmdHelp() {
|
|
|
22
23
|
console.log(` ${c.gray}--config Path to config file (default: capman.config.js)${c.reset}`)
|
|
23
24
|
console.log(` ${c.gray}--out Output path (default: manifest.json)${c.reset}`)
|
|
24
25
|
console.log(` ${c.gray}--manifest Manifest to read (default: manifest.json)${c.reset}`)
|
|
26
|
+
console.log(` ${c.gray} Requires API key. Run after --ai or --from.${c.reset}`)
|
|
27
|
+
console.log(` ${c.gray} Skips caps with ≥ 20 examples already.${c.reset}`)
|
|
25
28
|
console.log()
|
|
26
29
|
}
|
package/dist/cjs/engine.d.ts
CHANGED
|
@@ -47,6 +47,10 @@ export interface EngineOptions {
|
|
|
47
47
|
headers?: Record<string, string>;
|
|
48
48
|
/** Confidence threshold for keyword matcher (default: 50) */
|
|
49
49
|
threshold?: number;
|
|
50
|
+
/** BM25 TF saturation parameter (default: 1.5) */
|
|
51
|
+
bm25K1?: number;
|
|
52
|
+
/** BM25 length normalization parameter (default: 0.75) */
|
|
53
|
+
bm25B?: number;
|
|
50
54
|
/**
|
|
51
55
|
* Optional TTL for cache entries in milliseconds.
|
|
52
56
|
* Entries older than this are treated as misses and evicted on read.
|
|
@@ -97,14 +101,35 @@ export interface EngineOptions {
|
|
|
97
101
|
* @default 0.4
|
|
98
102
|
*/
|
|
99
103
|
fuzzyThreshold?: number;
|
|
104
|
+
/**
|
|
105
|
+
* When true, a 'marginal' verdict in balanced/accurate mode triggers a
|
|
106
|
+
* targeted LLM disambiguation between the top-2 candidates.
|
|
107
|
+
* Uses ~200 tokens vs ~4000 for full manifest — 93% cost reduction.
|
|
108
|
+
* Has no effect in cheap mode or when no llm is provided.
|
|
109
|
+
* @default false
|
|
110
|
+
*/
|
|
111
|
+
marginAwareLLM?: boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Override the adaptive margin threshold (0-100 points).
|
|
114
|
+
* When undefined, calibrated automatically from manifest score distribution.
|
|
115
|
+
*/
|
|
116
|
+
adaptiveMarginOverride?: number;
|
|
100
117
|
}
|
|
101
118
|
export interface EngineResult {
|
|
102
119
|
match: MatchResult;
|
|
103
120
|
resolution: ResolveResult;
|
|
104
121
|
resolvedVia: 'cache' | 'keyword' | 'llm';
|
|
105
122
|
durationMs: number;
|
|
106
|
-
/** Full execution trace — always present */
|
|
107
123
|
trace: ExecutionTrace;
|
|
124
|
+
verdict: 'clear' | 'marginal' | 'uncertain';
|
|
125
|
+
margin: number;
|
|
126
|
+
/**
|
|
127
|
+
* Required params that could not be extracted from the query.
|
|
128
|
+
* Only populated when extraction failed AND LLM was not used.
|
|
129
|
+
* When present, the agent should prompt the user for these values.
|
|
130
|
+
* Undefined when all required params were successfully extracted.
|
|
131
|
+
*/
|
|
132
|
+
missingParams?: string[];
|
|
108
133
|
}
|
|
109
134
|
export declare class CapmanEngine {
|
|
110
135
|
/** Maximum allowed query length in characters. Queries exceeding this throw RangeError. */
|
|
@@ -121,6 +146,12 @@ export declare class CapmanEngine {
|
|
|
121
146
|
private cacheTtlMs;
|
|
122
147
|
private fuzzyMatch;
|
|
123
148
|
private fuzzyThreshold;
|
|
149
|
+
private bm25Index;
|
|
150
|
+
private bm25Ceiling;
|
|
151
|
+
private bm25K1;
|
|
152
|
+
private bm25B;
|
|
153
|
+
private marginAwareLLM;
|
|
154
|
+
private adaptiveMargin;
|
|
124
155
|
private maxLLMCallsPerMinute;
|
|
125
156
|
private llmCooldownMs;
|
|
126
157
|
private llmCircuitBreakerThreshold;
|
|
@@ -223,5 +254,26 @@ export declare class CapmanEngine {
|
|
|
223
254
|
private applyLearningBoost;
|
|
224
255
|
private resolveOptions;
|
|
225
256
|
private recordLearning;
|
|
257
|
+
private calibrateBM25Ceiling;
|
|
258
|
+
/**
|
|
259
|
+
* Calibrates the adaptive margin threshold from the manifest's own score
|
|
260
|
+
* distribution. Runs each capability's first example against all other
|
|
261
|
+
* capabilities to find the typical inter-capability score spread.
|
|
262
|
+
* Dense overlapping vocabulary → lower margin (harder to separate).
|
|
263
|
+
* Sparse vocabulary → higher margin (easier to separate).
|
|
264
|
+
*
|
|
265
|
+
* Complexity: O(capabilities²) — runs at constructor time and on loadManifest().
|
|
266
|
+
* For manifests with ≤100 capabilities this is negligible (<10ms).
|
|
267
|
+
* For very large manifests (500+ capabilities), consider passing
|
|
268
|
+
* `adaptiveMarginOverride` to skip calibration.
|
|
269
|
+
*/
|
|
270
|
+
private calibrateAdaptiveMargin;
|
|
271
|
+
private computeVerdict;
|
|
272
|
+
/**
|
|
273
|
+
* Targeted disambiguation between top-2 candidates.
|
|
274
|
+
* Sends ~200 tokens instead of full manifest (~4000 tokens) — 93% cost reduction.
|
|
275
|
+
* Returns updated matchResult with LLM-preferred winner, or original on failure.
|
|
276
|
+
*/
|
|
277
|
+
private disambiguateLLM;
|
|
226
278
|
}
|
|
227
279
|
//# sourceMappingURL=engine.d.ts.map
|
package/dist/cjs/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAa,aAAa,EAA4F,MAAM,SAAS,CAAA;AACvM,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,YAAY,CAAA;AAK7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAMxC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,QAAQ,EAAE,QAAQ,CAAA;IAClB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,kDAAkD;IAClD,GAAG,CAAC,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAA;IAC9B,0FAA0F;IAC1F,KAAK,CAAC,EAAE,UAAU,GAAG,KAAK,CAAA;IAC1B,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,aAAa,GAAG,KAAK,CAAA;IAChC,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mDAAmD;IACnD,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAE7B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;;OAIG;IACH,0BAA0B,CAAC,EAAE,MAAM,CAAA;IAEnC;;;OAGG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAA;IAEjC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/engine.ts"],"names":[],"mappings":"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"}
|