kodingo-core 0.2.2 → 0.2.3
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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/src/query/query-engine.d.ts +60 -0
- package/dist/src/query/query-engine.d.ts.map +1 -0
- package/dist/src/query/query-engine.js +116 -0
- package/dist/src/query/query-engine.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -11,4 +11,5 @@ export * from "./src/domain/decision/decision";
|
|
|
11
11
|
export * from "./src/domain/decision/decision-outcome";
|
|
12
12
|
export * from "./src/domain/decision/decision-event";
|
|
13
13
|
export * from "./src/domain/decision/decision-errors";
|
|
14
|
+
export * from "./src/query/query-engine";
|
|
14
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC;AACnD,cAAc,sCAAsC,CAAC;AAErD,cAAc,yBAAyB,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAElD,cAAc,wCAAwC,CAAC;AACvD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wCAAwC,CAAC;AACvD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,oCAAoC,CAAC;AACnD,cAAc,sCAAsC,CAAC;AAErD,cAAc,yBAAyB,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,oCAAoC,CAAC;AACnD,cAAc,mCAAmC,CAAC;AAElD,cAAc,wCAAwC,CAAC;AACvD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,wCAAwC,CAAC;AACvD,cAAc,sCAAsC,CAAC;AACrD,cAAc,uCAAuC,CAAC;AACtD,cAAc,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -27,4 +27,5 @@ __exportStar(require("./src/domain/decision/decision"), exports);
|
|
|
27
27
|
__exportStar(require("./src/domain/decision/decision-outcome"), exports);
|
|
28
28
|
__exportStar(require("./src/domain/decision/decision-event"), exports);
|
|
29
29
|
__exportStar(require("./src/domain/decision/decision-errors"), exports);
|
|
30
|
+
__exportStar(require("./src/query/query-engine"), exports);
|
|
30
31
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qEAAmD;AACnD,uEAAqD;AAErD,0DAAwC;AACxC,6DAA2C;AAC3C,yDAAuC;AACvC,yDAAuC;AAEvC,qEAAmD;AACnD,oEAAkD;AAElD,yEAAuD;AACvD,iEAA+C;AAC/C,yEAAuD;AACvD,uEAAqD;AACrD,wEAAsD"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qEAAmD;AACnD,uEAAqD;AAErD,0DAAwC;AACxC,6DAA2C;AAC3C,yDAAuC;AACvC,yDAAuC;AAEvC,qEAAmD;AACnD,oEAAkD;AAElD,yEAAuD;AACvD,iEAA+C;AAC/C,yEAAuD;AACvD,uEAAqD;AACrD,wEAAsD;AACtD,2DAAyC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* query-engine.ts
|
|
3
|
+
*
|
|
4
|
+
* Core domain logic for the Kortex query engine.
|
|
5
|
+
* Defines types, ranking, and synthesis interface.
|
|
6
|
+
* No LLM calls, no DB access — pure deterministic domain logic.
|
|
7
|
+
*/
|
|
8
|
+
import type { MemoryRecord } from "../domain/memory/project-memory";
|
|
9
|
+
export type QueryIntentType = "concept" | "symbol" | "decision_history" | "comparison" | "general";
|
|
10
|
+
export interface QueryIntent {
|
|
11
|
+
raw: string;
|
|
12
|
+
type: QueryIntentType;
|
|
13
|
+
entities: string[];
|
|
14
|
+
symbolHint?: string;
|
|
15
|
+
confidence: number;
|
|
16
|
+
}
|
|
17
|
+
export interface QuerySource {
|
|
18
|
+
memory: MemoryRecord;
|
|
19
|
+
relevanceScore: number;
|
|
20
|
+
vectorScore: number;
|
|
21
|
+
domainScore: number;
|
|
22
|
+
}
|
|
23
|
+
export interface QueryResult {
|
|
24
|
+
answer: string;
|
|
25
|
+
sources: QuerySource[];
|
|
26
|
+
intent: QueryIntent;
|
|
27
|
+
synthesisedAt: Date;
|
|
28
|
+
totalCandidates: number;
|
|
29
|
+
}
|
|
30
|
+
export interface SynthesisPort {
|
|
31
|
+
/**
|
|
32
|
+
* Generate a natural language answer grounded in the provided memories.
|
|
33
|
+
* Implementations use an LLM with the memories as context.
|
|
34
|
+
*/
|
|
35
|
+
synthesise(params: {
|
|
36
|
+
intent: QueryIntent;
|
|
37
|
+
memories: MemoryRecord[];
|
|
38
|
+
projectName?: string;
|
|
39
|
+
}): Promise<{
|
|
40
|
+
answer: string;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Re-ranks vector search candidates using domain scoring.
|
|
45
|
+
* Called after pgvector retrieval to apply Kortex-specific ranking rules.
|
|
46
|
+
*
|
|
47
|
+
* Combined score = (vectorScore * 0.6) + (domainScore * 0.4)
|
|
48
|
+
* Vector similarity is weighted higher but domain scoring prevents
|
|
49
|
+
* low-confidence or denied memories from surfacing.
|
|
50
|
+
*/
|
|
51
|
+
export declare function rankMemoriesForQuery(candidates: Array<{
|
|
52
|
+
memory: MemoryRecord;
|
|
53
|
+
vectorScore: number;
|
|
54
|
+
}>, intent: QueryIntent): QuerySource[];
|
|
55
|
+
/**
|
|
56
|
+
* Builds the context string passed to the LLM for synthesis.
|
|
57
|
+
* Formats ranked memories into a structured prompt context.
|
|
58
|
+
*/
|
|
59
|
+
export declare function buildQueryContext(sources: QuerySource[], maxSources?: number): string;
|
|
60
|
+
//# sourceMappingURL=query-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-engine.d.ts","sourceRoot":"","sources":["../../../src/query/query-engine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAIpE,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,QAAQ,GACR,kBAAkB,GAClB,YAAY,GACZ,SAAS,CAAC;AAEd,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,YAAY,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,aAAa,EAAE,IAAI,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAID,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE;QACjB,MAAM,EAAE,WAAW,CAAC;QACpB,QAAQ,EAAE,YAAY,EAAE,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjC;AAuCD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,KAAK,CAAC;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,EAChE,MAAM,EAAE,WAAW,GAClB,WAAW,EAAE,CAoDf;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,WAAW,EAAE,EACtB,UAAU,SAAI,GACb,MAAM,CAgBR"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* query-engine.ts
|
|
4
|
+
*
|
|
5
|
+
* Core domain logic for the Kortex query engine.
|
|
6
|
+
* Defines types, ranking, and synthesis interface.
|
|
7
|
+
* No LLM calls, no DB access — pure deterministic domain logic.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.rankMemoriesForQuery = rankMemoriesForQuery;
|
|
11
|
+
exports.buildQueryContext = buildQueryContext;
|
|
12
|
+
// ── Ranking ───────────────────────────────────────────────────────────────────
|
|
13
|
+
const STATUS_WEIGHT = {
|
|
14
|
+
affirmed: 1.0,
|
|
15
|
+
proposed: 0.6,
|
|
16
|
+
ignored: 0.3,
|
|
17
|
+
denied: 0.0,
|
|
18
|
+
};
|
|
19
|
+
const INTENT_TYPE_WEIGHT = {
|
|
20
|
+
concept: {
|
|
21
|
+
decision: 1.0,
|
|
22
|
+
context: 0.8,
|
|
23
|
+
note: 0.6,
|
|
24
|
+
},
|
|
25
|
+
symbol: {
|
|
26
|
+
context: 1.0,
|
|
27
|
+
decision: 0.8,
|
|
28
|
+
note: 0.6,
|
|
29
|
+
},
|
|
30
|
+
decision_history: {
|
|
31
|
+
decision: 1.0,
|
|
32
|
+
note: 0.7,
|
|
33
|
+
context: 0.5,
|
|
34
|
+
},
|
|
35
|
+
comparison: {
|
|
36
|
+
decision: 1.0,
|
|
37
|
+
context: 0.8,
|
|
38
|
+
note: 0.6,
|
|
39
|
+
},
|
|
40
|
+
general: {
|
|
41
|
+
decision: 0.9,
|
|
42
|
+
context: 0.9,
|
|
43
|
+
note: 0.7,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Re-ranks vector search candidates using domain scoring.
|
|
48
|
+
* Called after pgvector retrieval to apply Kortex-specific ranking rules.
|
|
49
|
+
*
|
|
50
|
+
* Combined score = (vectorScore * 0.6) + (domainScore * 0.4)
|
|
51
|
+
* Vector similarity is weighted higher but domain scoring prevents
|
|
52
|
+
* low-confidence or denied memories from surfacing.
|
|
53
|
+
*/
|
|
54
|
+
function rankMemoriesForQuery(candidates, intent) {
|
|
55
|
+
const intentWeights = INTENT_TYPE_WEIGHT[intent.type] ?? INTENT_TYPE_WEIGHT.general;
|
|
56
|
+
return candidates
|
|
57
|
+
.map(({ memory, vectorScore }) => {
|
|
58
|
+
const statusScore = STATUS_WEIGHT[memory.status] ?? 0;
|
|
59
|
+
const typeScore = intentWeights[memory.type] ?? 0.5;
|
|
60
|
+
const confidenceScore = memory.confidence;
|
|
61
|
+
// Boost if symbol matches the hint exactly
|
|
62
|
+
const symbolBoost = intent.symbolHint &&
|
|
63
|
+
memory.symbol?.toLowerCase().includes(intent.symbolHint.toLowerCase())
|
|
64
|
+
? 0.2
|
|
65
|
+
: 0;
|
|
66
|
+
// Boost if any entity matches tags or symbol
|
|
67
|
+
const entityBoost = intent.entities.some(e => memory.tags?.some(t => t.toLowerCase().includes(e.toLowerCase())) ||
|
|
68
|
+
memory.symbol?.toLowerCase().includes(e.toLowerCase()) ||
|
|
69
|
+
memory.title?.toLowerCase().includes(e.toLowerCase()))
|
|
70
|
+
? 0.15
|
|
71
|
+
: 0;
|
|
72
|
+
// Recency boost — memories updated in last 30 days get a small boost
|
|
73
|
+
const daysSinceUpdate = (Date.now() - new Date(memory.updatedAt).getTime()) / (1000 * 60 * 60 * 24);
|
|
74
|
+
const recencyBoost = daysSinceUpdate < 30 ? 0.05 : 0;
|
|
75
|
+
const domainScore = Math.min(1, statusScore * 0.4 +
|
|
76
|
+
typeScore * 0.25 +
|
|
77
|
+
confidenceScore * 0.2 +
|
|
78
|
+
symbolBoost +
|
|
79
|
+
entityBoost +
|
|
80
|
+
recencyBoost);
|
|
81
|
+
// Denied memories never surface regardless of vector score
|
|
82
|
+
if (memory.status === "denied") {
|
|
83
|
+
return { memory, vectorScore, domainScore: 0, relevanceScore: 0 };
|
|
84
|
+
}
|
|
85
|
+
const relevanceScore = vectorScore * 0.6 + domainScore * 0.4;
|
|
86
|
+
return { memory, vectorScore, domainScore, relevanceScore };
|
|
87
|
+
})
|
|
88
|
+
.filter(s => s.relevanceScore > 0)
|
|
89
|
+
.sort((a, b) => b.relevanceScore - a.relevanceScore);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Builds the context string passed to the LLM for synthesis.
|
|
93
|
+
* Formats ranked memories into a structured prompt context.
|
|
94
|
+
*/
|
|
95
|
+
function buildQueryContext(sources, maxSources = 8) {
|
|
96
|
+
return sources
|
|
97
|
+
.slice(0, maxSources)
|
|
98
|
+
.map((s, i) => {
|
|
99
|
+
const m = s.memory;
|
|
100
|
+
const lines = [];
|
|
101
|
+
lines.push(`[Source ${i + 1}]`);
|
|
102
|
+
if (m.title)
|
|
103
|
+
lines.push(`Title: ${m.title}`);
|
|
104
|
+
if (m.symbol)
|
|
105
|
+
lines.push(`Symbol: ${m.symbol}`);
|
|
106
|
+
if (m.repo)
|
|
107
|
+
lines.push(`Repo: ${m.repo}`);
|
|
108
|
+
lines.push(`Type: ${m.type} | Status: ${m.status} | Confidence: ${Math.round(m.confidence * 100)}%`);
|
|
109
|
+
if (m.tags?.length)
|
|
110
|
+
lines.push(`Tags: ${m.tags.join(", ")}`);
|
|
111
|
+
lines.push(`Content: ${m.content}`);
|
|
112
|
+
return lines.join("\n");
|
|
113
|
+
})
|
|
114
|
+
.join("\n\n---\n\n");
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=query-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-engine.js","sourceRoot":"","sources":["../../../src/query/query-engine.ts"],"names":[],"mappings":"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"}
|