@yugenlab/vaayu 0.1.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/LICENSE +21 -0
- package/README.md +365 -0
- package/chunks/chunk-E5A3SCDJ.js +246 -0
- package/chunks/chunk-G5VYCA6O.js +69 -0
- package/chunks/chunk-H76V36OF.js +1029 -0
- package/chunks/chunk-HAPVUJ6A.js +238 -0
- package/chunks/chunk-IEKAYVA3.js +137 -0
- package/chunks/chunk-IGKYKEKT.js +43 -0
- package/chunks/chunk-IIET2K6D.js +7728 -0
- package/chunks/chunk-ITIVYGUG.js +347 -0
- package/chunks/chunk-JAWZ7ANC.js +208 -0
- package/chunks/chunk-JZU37VQ5.js +714 -0
- package/chunks/chunk-KC6NRZ7U.js +198 -0
- package/chunks/chunk-KDRROLVN.js +433 -0
- package/chunks/chunk-L7JICQBW.js +1006 -0
- package/chunks/chunk-MINFB5LT.js +1479 -0
- package/chunks/chunk-MJ74G5RB.js +5816 -0
- package/chunks/chunk-S4TBVCL2.js +2158 -0
- package/chunks/chunk-SMVJRPAH.js +2753 -0
- package/chunks/chunk-U6OLJ36B.js +438 -0
- package/chunks/chunk-URGEODS5.js +752 -0
- package/chunks/chunk-YSU3BWV6.js +123 -0
- package/chunks/consolidation-indexer-TOTTDZXW.js +21 -0
- package/chunks/day-consolidation-NKO63HZQ.js +24 -0
- package/chunks/graphrag-ZI2FSU7S.js +13 -0
- package/chunks/hierarchical-temporal-search-ZD46UMKR.js +8 -0
- package/chunks/hybrid-search-ZVLZVGFS.js +19 -0
- package/chunks/memory-store-KNJPMBLQ.js +17 -0
- package/chunks/periodic-consolidation-BPKOZDGB.js +10 -0
- package/chunks/postgres-3ZXBYTPC.js +8 -0
- package/chunks/recall-GMVHWQWW.js +20 -0
- package/chunks/search-7HZETVMZ.js +18 -0
- package/chunks/session-store-XKPGKXUS.js +44 -0
- package/chunks/sqlite-JPF5TICX.js +152 -0
- package/chunks/src-6GVZTUH6.js +12 -0
- package/chunks/src-QAXOD5SB.js +273 -0
- package/chunks/suncalc-NOHGYHDU.js +186 -0
- package/chunks/tree-RSHKDTCR.js +10 -0
- package/gateway.js +61944 -0
- package/package.json +51 -0
- package/pair-cli.js +133 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
// ../chitragupta/packages/core/dist/errors.js
|
|
2
|
+
var ChitraguptaError = class extends Error {
|
|
3
|
+
code;
|
|
4
|
+
constructor(message, code, cause) {
|
|
5
|
+
super(message, { cause });
|
|
6
|
+
this.name = "ChitraguptaError";
|
|
7
|
+
this.code = code;
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
var SessionError = class extends ChitraguptaError {
|
|
11
|
+
constructor(message, cause) {
|
|
12
|
+
super(message, "SESSION_ERROR", cause);
|
|
13
|
+
this.name = "SessionError";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
var MemoryError = class extends ChitraguptaError {
|
|
17
|
+
constructor(message, cause) {
|
|
18
|
+
super(message, "MEMORY_ERROR", cause);
|
|
19
|
+
this.name = "MemoryError";
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// ../chitragupta/packages/core/dist/config.js
|
|
24
|
+
import path from "path";
|
|
25
|
+
function getChitraguptaHome() {
|
|
26
|
+
const override = process.env.CHITRAGUPTA_HOME?.trim();
|
|
27
|
+
if (override)
|
|
28
|
+
return override;
|
|
29
|
+
return path.join(process.env.HOME || process.env.USERPROFILE || "~", ".chitragupta");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ../chitragupta/packages/core/dist/auth/rbac.js
|
|
33
|
+
var PERMISSIONS = {
|
|
34
|
+
// Session
|
|
35
|
+
READ_SESSION: "read:session",
|
|
36
|
+
WRITE_SESSION: "write:session",
|
|
37
|
+
// Chat
|
|
38
|
+
READ_CHAT: "read:chat",
|
|
39
|
+
WRITE_CHAT: "write:chat",
|
|
40
|
+
// Jobs
|
|
41
|
+
READ_JOBS: "read:jobs",
|
|
42
|
+
WRITE_JOBS: "write:jobs",
|
|
43
|
+
// Agents
|
|
44
|
+
READ_AGENTS: "read:agents",
|
|
45
|
+
WRITE_AGENTS: "write:agents",
|
|
46
|
+
ADMIN_AGENTS: "admin:agents",
|
|
47
|
+
// Memory
|
|
48
|
+
READ_MEMORY: "read:memory",
|
|
49
|
+
WRITE_MEMORY: "write:memory",
|
|
50
|
+
DELETE_MEMORY: "delete:memory",
|
|
51
|
+
// Metrics
|
|
52
|
+
READ_METRICS: "read:metrics",
|
|
53
|
+
// Providers & Tools
|
|
54
|
+
READ_PROVIDERS: "read:providers",
|
|
55
|
+
READ_TOOLS: "read:tools",
|
|
56
|
+
// Admin
|
|
57
|
+
ADMIN_SYSTEM: "admin:system"
|
|
58
|
+
};
|
|
59
|
+
var WILDCARD_PERMISSION = "*";
|
|
60
|
+
var ALL_PERMISSIONS = new Set(Object.values(PERMISSIONS));
|
|
61
|
+
ALL_PERMISSIONS.add(WILDCARD_PERMISSION);
|
|
62
|
+
var OPERATOR_ROLE = {
|
|
63
|
+
name: "operator",
|
|
64
|
+
description: "Read and write access to sessions, chat, jobs, agents, and memory.",
|
|
65
|
+
permissions: /* @__PURE__ */ new Set([
|
|
66
|
+
PERMISSIONS.READ_SESSION,
|
|
67
|
+
PERMISSIONS.WRITE_SESSION,
|
|
68
|
+
PERMISSIONS.READ_CHAT,
|
|
69
|
+
PERMISSIONS.WRITE_CHAT,
|
|
70
|
+
PERMISSIONS.READ_JOBS,
|
|
71
|
+
PERMISSIONS.WRITE_JOBS,
|
|
72
|
+
PERMISSIONS.READ_AGENTS,
|
|
73
|
+
PERMISSIONS.WRITE_AGENTS,
|
|
74
|
+
PERMISSIONS.READ_MEMORY,
|
|
75
|
+
PERMISSIONS.WRITE_MEMORY,
|
|
76
|
+
PERMISSIONS.DELETE_MEMORY,
|
|
77
|
+
PERMISSIONS.READ_METRICS,
|
|
78
|
+
PERMISSIONS.READ_PROVIDERS,
|
|
79
|
+
PERMISSIONS.READ_TOOLS
|
|
80
|
+
])
|
|
81
|
+
};
|
|
82
|
+
var VIEWER_ROLE = {
|
|
83
|
+
name: "viewer",
|
|
84
|
+
description: "Read-only access to sessions, agents, memory, and metrics.",
|
|
85
|
+
permissions: /* @__PURE__ */ new Set([
|
|
86
|
+
PERMISSIONS.READ_SESSION,
|
|
87
|
+
PERMISSIONS.READ_CHAT,
|
|
88
|
+
PERMISSIONS.READ_JOBS,
|
|
89
|
+
PERMISSIONS.READ_AGENTS,
|
|
90
|
+
PERMISSIONS.READ_MEMORY,
|
|
91
|
+
PERMISSIONS.READ_METRICS,
|
|
92
|
+
PERMISSIONS.READ_PROVIDERS,
|
|
93
|
+
PERMISSIONS.READ_TOOLS
|
|
94
|
+
])
|
|
95
|
+
};
|
|
96
|
+
var AGENT_ROLE = {
|
|
97
|
+
name: "agent",
|
|
98
|
+
description: "Limited API access for programmatic sub-agent use.",
|
|
99
|
+
permissions: /* @__PURE__ */ new Set([
|
|
100
|
+
PERMISSIONS.READ_SESSION,
|
|
101
|
+
PERMISSIONS.WRITE_CHAT,
|
|
102
|
+
PERMISSIONS.READ_AGENTS,
|
|
103
|
+
PERMISSIONS.READ_MEMORY,
|
|
104
|
+
PERMISSIONS.WRITE_MEMORY,
|
|
105
|
+
PERMISSIONS.READ_TOOLS
|
|
106
|
+
])
|
|
107
|
+
};
|
|
108
|
+
var ROUTE_PERMISSIONS = /* @__PURE__ */ new Map([
|
|
109
|
+
// Public
|
|
110
|
+
["GET /api/health", null],
|
|
111
|
+
// Sessions
|
|
112
|
+
["GET /api/sessions", PERMISSIONS.READ_SESSION],
|
|
113
|
+
["GET /api/sessions/:id", PERMISSIONS.READ_SESSION],
|
|
114
|
+
["POST /api/sessions", PERMISSIONS.WRITE_SESSION],
|
|
115
|
+
// Chat
|
|
116
|
+
["POST /api/chat", PERMISSIONS.WRITE_CHAT],
|
|
117
|
+
// Jobs
|
|
118
|
+
["GET /api/jobs", PERMISSIONS.READ_JOBS],
|
|
119
|
+
["GET /api/jobs/stats", PERMISSIONS.READ_JOBS],
|
|
120
|
+
["GET /api/jobs/:id", PERMISSIONS.READ_JOBS],
|
|
121
|
+
["POST /api/jobs", PERMISSIONS.WRITE_JOBS],
|
|
122
|
+
["POST /api/jobs/:id/cancel", PERMISSIONS.WRITE_JOBS],
|
|
123
|
+
// Agents
|
|
124
|
+
["GET /api/agents", PERMISSIONS.READ_AGENTS],
|
|
125
|
+
["GET /api/agents/tree", PERMISSIONS.READ_AGENTS],
|
|
126
|
+
["GET /api/agents/stats", PERMISSIONS.READ_AGENTS],
|
|
127
|
+
["GET /api/agents/:id", PERMISSIONS.READ_AGENTS],
|
|
128
|
+
["GET /api/agents/:id/tree", PERMISSIONS.READ_AGENTS],
|
|
129
|
+
["POST /api/agents/:id/spawn", PERMISSIONS.WRITE_AGENTS],
|
|
130
|
+
["POST /api/agents/:id/abort", PERMISSIONS.ADMIN_AGENTS],
|
|
131
|
+
["POST /api/agents/:id/prompt", PERMISSIONS.WRITE_AGENTS],
|
|
132
|
+
["GET /api/agent/status", PERMISSIONS.READ_AGENTS],
|
|
133
|
+
["POST /api/agent/reset", PERMISSIONS.ADMIN_AGENTS],
|
|
134
|
+
// Memory
|
|
135
|
+
["GET /api/memory/scopes", PERMISSIONS.READ_MEMORY],
|
|
136
|
+
["GET /api/memory/:scope", PERMISSIONS.READ_MEMORY],
|
|
137
|
+
["PUT /api/memory/:scope", PERMISSIONS.WRITE_MEMORY],
|
|
138
|
+
["POST /api/memory/:scope", PERMISSIONS.WRITE_MEMORY],
|
|
139
|
+
["POST /api/memory/search", PERMISSIONS.READ_MEMORY],
|
|
140
|
+
["DELETE /api/memory/:scope", PERMISSIONS.DELETE_MEMORY],
|
|
141
|
+
// Providers & Tools
|
|
142
|
+
["GET /api/providers", PERMISSIONS.READ_PROVIDERS],
|
|
143
|
+
["GET /api/tools", PERMISSIONS.READ_TOOLS],
|
|
144
|
+
// Auth (public — these handle their own auth)
|
|
145
|
+
["POST /api/auth/token", null],
|
|
146
|
+
["POST /api/auth/refresh", null],
|
|
147
|
+
["GET /api/auth/me", null]
|
|
148
|
+
]);
|
|
149
|
+
|
|
150
|
+
// ../chitragupta/packages/core/dist/auth/oauth.js
|
|
151
|
+
var JWKS_CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
152
|
+
|
|
153
|
+
// ../chitragupta/packages/core/dist/observability/logger.js
|
|
154
|
+
var LogLevel;
|
|
155
|
+
(function(LogLevel2) {
|
|
156
|
+
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
|
|
157
|
+
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
158
|
+
LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
|
|
159
|
+
LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
|
|
160
|
+
LogLevel2[LogLevel2["FATAL"] = 4] = "FATAL";
|
|
161
|
+
})(LogLevel || (LogLevel = {}));
|
|
162
|
+
var LOG_LEVEL_NAMES = {
|
|
163
|
+
[LogLevel.DEBUG]: "DEBUG",
|
|
164
|
+
[LogLevel.INFO]: "INFO",
|
|
165
|
+
[LogLevel.WARN]: "WARN",
|
|
166
|
+
[LogLevel.ERROR]: "ERROR",
|
|
167
|
+
[LogLevel.FATAL]: "FATAL"
|
|
168
|
+
};
|
|
169
|
+
var LOG_LEVEL_PARSE = {
|
|
170
|
+
debug: LogLevel.DEBUG,
|
|
171
|
+
info: LogLevel.INFO,
|
|
172
|
+
warn: LogLevel.WARN,
|
|
173
|
+
error: LogLevel.ERROR,
|
|
174
|
+
fatal: LogLevel.FATAL
|
|
175
|
+
};
|
|
176
|
+
var LEVEL_COLORS = {
|
|
177
|
+
[LogLevel.DEBUG]: "\x1B[36m",
|
|
178
|
+
// cyan
|
|
179
|
+
[LogLevel.INFO]: "\x1B[32m",
|
|
180
|
+
// green
|
|
181
|
+
[LogLevel.WARN]: "\x1B[33m",
|
|
182
|
+
// yellow
|
|
183
|
+
[LogLevel.ERROR]: "\x1B[31m",
|
|
184
|
+
// red
|
|
185
|
+
[LogLevel.FATAL]: "\x1B[35;1m"
|
|
186
|
+
// bold magenta
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
// ../chitragupta/packages/core/dist/observability/tracing.js
|
|
190
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
191
|
+
var spanStorage = new AsyncLocalStorage();
|
|
192
|
+
|
|
193
|
+
export {
|
|
194
|
+
SessionError,
|
|
195
|
+
MemoryError,
|
|
196
|
+
getChitraguptaHome
|
|
197
|
+
};
|
|
198
|
+
//# sourceMappingURL=chunk-KC6NRZ7U.js.map
|
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
import {
|
|
2
|
+
searchSessions
|
|
3
|
+
} from "./chunk-ITIVYGUG.js";
|
|
4
|
+
|
|
5
|
+
// ../chitragupta/packages/smriti/src/hybrid-search.ts
|
|
6
|
+
var PRAMANA_RELIABILITY = {
|
|
7
|
+
pratyaksha: 1,
|
|
8
|
+
anumana: 0.85,
|
|
9
|
+
shabda: 0.75,
|
|
10
|
+
upamana: 0.6,
|
|
11
|
+
arthapatti: 0.5,
|
|
12
|
+
anupalabdhi: 0.4
|
|
13
|
+
};
|
|
14
|
+
var DEFAULT_CONFIG = {
|
|
15
|
+
k: 60,
|
|
16
|
+
topK: 10,
|
|
17
|
+
enableBM25: true,
|
|
18
|
+
enableVector: true,
|
|
19
|
+
enableGraphRAG: true,
|
|
20
|
+
pramanaWeight: 0.1,
|
|
21
|
+
enablePramana: true,
|
|
22
|
+
minScore: 0
|
|
23
|
+
};
|
|
24
|
+
function gaussianRandom() {
|
|
25
|
+
const u1 = Math.random();
|
|
26
|
+
const u2 = Math.random();
|
|
27
|
+
return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
|
|
28
|
+
}
|
|
29
|
+
function sampleGamma(shape) {
|
|
30
|
+
if (shape < 1) {
|
|
31
|
+
const g = sampleGamma(shape + 1);
|
|
32
|
+
return g * Math.pow(Math.random(), 1 / shape);
|
|
33
|
+
}
|
|
34
|
+
const d = shape - 1 / 3;
|
|
35
|
+
const c = 1 / Math.sqrt(9 * d);
|
|
36
|
+
for (; ; ) {
|
|
37
|
+
let z;
|
|
38
|
+
let v;
|
|
39
|
+
do {
|
|
40
|
+
z = gaussianRandom();
|
|
41
|
+
v = 1 + c * z;
|
|
42
|
+
} while (v <= 0);
|
|
43
|
+
v = v * v * v;
|
|
44
|
+
const u = Math.random();
|
|
45
|
+
const zSq = z * z;
|
|
46
|
+
if (u < 1 - 0.0331 * (zSq * zSq)) return d * v;
|
|
47
|
+
if (Math.log(u) < 0.5 * zSq + d * (1 - v + Math.log(v))) return d * v;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function sampleBeta(alpha, beta) {
|
|
51
|
+
const x = sampleGamma(alpha);
|
|
52
|
+
const y = sampleGamma(beta);
|
|
53
|
+
if (x + y === 0) return 0.5;
|
|
54
|
+
return x / (x + y);
|
|
55
|
+
}
|
|
56
|
+
var SIGNAL_INDEX = {
|
|
57
|
+
bm25: 0,
|
|
58
|
+
vector: 1,
|
|
59
|
+
graphrag: 2,
|
|
60
|
+
pramana: 3
|
|
61
|
+
};
|
|
62
|
+
var NUM_SIGNALS = 4;
|
|
63
|
+
var HybridWeightLearner = class {
|
|
64
|
+
/** Success counts (α) for each of the 4 signals. */
|
|
65
|
+
_alphas;
|
|
66
|
+
/** Failure counts (β) for each of the 4 signals. */
|
|
67
|
+
_betas;
|
|
68
|
+
/** Total feedback events received. */
|
|
69
|
+
_totalFeedback;
|
|
70
|
+
/**
|
|
71
|
+
* @param priorAlpha - Initial α for all signals. Default: 1 (uniform prior).
|
|
72
|
+
* @param priorBeta - Initial β for all signals. Default: 1 (uniform prior).
|
|
73
|
+
*/
|
|
74
|
+
constructor(priorAlpha = 1, priorBeta = 1) {
|
|
75
|
+
this._alphas = new Float64Array(NUM_SIGNALS);
|
|
76
|
+
this._betas = new Float64Array(NUM_SIGNALS);
|
|
77
|
+
this._totalFeedback = 0;
|
|
78
|
+
for (let i = 0; i < NUM_SIGNALS; i++) {
|
|
79
|
+
this._alphas[i] = priorAlpha;
|
|
80
|
+
this._betas[i] = priorBeta;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Sample a weight vector from the Beta posteriors.
|
|
85
|
+
*
|
|
86
|
+
* Each signal's weight is sampled from Beta(α_i, β_i), then the 4
|
|
87
|
+
* weights are normalized to sum to 1 (Dirichlet-like normalization).
|
|
88
|
+
*
|
|
89
|
+
* @returns Normalized weight vector { bm25, vector, graphrag, pramana }.
|
|
90
|
+
*/
|
|
91
|
+
sample() {
|
|
92
|
+
const raw = new Float64Array(NUM_SIGNALS);
|
|
93
|
+
let sum = 0;
|
|
94
|
+
for (let i = 0; i < NUM_SIGNALS; i++) {
|
|
95
|
+
raw[i] = sampleBeta(this._alphas[i], this._betas[i]);
|
|
96
|
+
sum += raw[i];
|
|
97
|
+
}
|
|
98
|
+
if (sum < 1e-12) {
|
|
99
|
+
return { bm25: 0.25, vector: 0.25, graphrag: 0.25, pramana: 0.25 };
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
bm25: raw[0] / sum,
|
|
103
|
+
vector: raw[1] / sum,
|
|
104
|
+
graphrag: raw[2] / sum,
|
|
105
|
+
pramana: raw[3] / sum
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Update a signal's posterior after observing feedback.
|
|
110
|
+
*
|
|
111
|
+
* @param signal - Which signal to update.
|
|
112
|
+
* @param success - true = positive feedback (user found result useful),
|
|
113
|
+
* false = negative feedback (result was irrelevant).
|
|
114
|
+
*/
|
|
115
|
+
update(signal, success) {
|
|
116
|
+
const idx = SIGNAL_INDEX[signal];
|
|
117
|
+
if (success) {
|
|
118
|
+
this._alphas[idx] += 1;
|
|
119
|
+
} else {
|
|
120
|
+
this._betas[idx] += 1;
|
|
121
|
+
}
|
|
122
|
+
this._totalFeedback += 1;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get the posterior mean for each signal: α / (α + β).
|
|
126
|
+
* Useful for diagnostics and logging.
|
|
127
|
+
*/
|
|
128
|
+
means() {
|
|
129
|
+
const m = (i) => this._alphas[i] / (this._alphas[i] + this._betas[i]);
|
|
130
|
+
return { bm25: m(0), vector: m(1), graphrag: m(2), pramana: m(3) };
|
|
131
|
+
}
|
|
132
|
+
/** Total number of feedback events recorded. */
|
|
133
|
+
get totalFeedback() {
|
|
134
|
+
return this._totalFeedback;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Serialize the learner state for persistence.
|
|
138
|
+
*
|
|
139
|
+
* @returns A plain object suitable for JSON serialization.
|
|
140
|
+
*/
|
|
141
|
+
serialize() {
|
|
142
|
+
return {
|
|
143
|
+
alphas: Array.from(this._alphas),
|
|
144
|
+
betas: Array.from(this._betas),
|
|
145
|
+
totalFeedback: this._totalFeedback
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Restore the learner state from a serialized object.
|
|
150
|
+
*
|
|
151
|
+
* @param data - Previously serialized state from `serialize()`.
|
|
152
|
+
*/
|
|
153
|
+
restore(data) {
|
|
154
|
+
if (!data || !Array.isArray(data.alphas) || !Array.isArray(data.betas) || data.alphas.length !== NUM_SIGNALS || data.betas.length !== NUM_SIGNALS) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
for (let i = 0; i < NUM_SIGNALS; i++) {
|
|
158
|
+
this._alphas[i] = data.alphas[i];
|
|
159
|
+
this._betas[i] = data.betas[i];
|
|
160
|
+
}
|
|
161
|
+
this._totalFeedback = data.totalFeedback ?? 0;
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
function shouldRetrieve(query) {
|
|
165
|
+
const lower = query.toLowerCase().trim();
|
|
166
|
+
const gapPatterns = [
|
|
167
|
+
/\bwhat did\b/,
|
|
168
|
+
/\bwhen did\b/,
|
|
169
|
+
/\bhow did\b/,
|
|
170
|
+
/\bwhy did\b/,
|
|
171
|
+
/\bdo you remember\b/,
|
|
172
|
+
/\bpreviously\b/,
|
|
173
|
+
/\blast time\b/,
|
|
174
|
+
/\bearlier\b/,
|
|
175
|
+
/\bbefore\b/,
|
|
176
|
+
/\brecall\b/,
|
|
177
|
+
/\bhistory\b/,
|
|
178
|
+
/\bwe discussed\b/,
|
|
179
|
+
/\bwe decided\b/,
|
|
180
|
+
/\bwe agreed\b/,
|
|
181
|
+
/\bwhat was\b/,
|
|
182
|
+
/\bwhat is the status\b/,
|
|
183
|
+
/\bfind\b.*\b(file|code|function|class|module)\b/,
|
|
184
|
+
/\bsearch\b/,
|
|
185
|
+
/\blook up\b/,
|
|
186
|
+
/\bshow me\b.*\bfrom\b/
|
|
187
|
+
];
|
|
188
|
+
for (const pattern of gapPatterns) {
|
|
189
|
+
if (pattern.test(lower)) return true;
|
|
190
|
+
}
|
|
191
|
+
if (lower.endsWith("?") && lower.length > 20) return true;
|
|
192
|
+
if (/session[:\s]/i.test(lower)) return true;
|
|
193
|
+
if (/\bproject\b.*\b(memory|context|knowledge)\b/i.test(lower)) return true;
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
var HybridSearchEngine = class {
|
|
197
|
+
recallEngine;
|
|
198
|
+
graphEngine;
|
|
199
|
+
config;
|
|
200
|
+
weightLearner;
|
|
201
|
+
kalaChakra;
|
|
202
|
+
constructor(config, recallEngine, graphEngine, weightLearner) {
|
|
203
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
204
|
+
this.recallEngine = recallEngine ?? null;
|
|
205
|
+
this.graphEngine = graphEngine ?? null;
|
|
206
|
+
this.weightLearner = weightLearner ?? null;
|
|
207
|
+
this.kalaChakra = null;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Set or replace the RecallEngine instance.
|
|
211
|
+
*/
|
|
212
|
+
setRecallEngine(engine) {
|
|
213
|
+
this.recallEngine = engine;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Set or replace the GraphRAGEngine instance.
|
|
217
|
+
*/
|
|
218
|
+
setGraphEngine(engine) {
|
|
219
|
+
this.graphEngine = engine;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Set or replace the HybridWeightLearner instance.
|
|
223
|
+
*/
|
|
224
|
+
setWeightLearner(learner) {
|
|
225
|
+
this.weightLearner = learner;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Get the current HybridWeightLearner, or null if not set.
|
|
229
|
+
*/
|
|
230
|
+
getWeightLearner() {
|
|
231
|
+
return this.weightLearner;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Set or replace the KalaChakra temporal awareness engine.
|
|
235
|
+
* When set, search results with timestamps receive a temporal boost.
|
|
236
|
+
*/
|
|
237
|
+
setKalaChakra(kala) {
|
|
238
|
+
this.kalaChakra = kala;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Get the current KalaChakra instance, or null if not set.
|
|
242
|
+
*/
|
|
243
|
+
getKalaChakra() {
|
|
244
|
+
return this.kalaChakra;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Record feedback for a search result.
|
|
248
|
+
*
|
|
249
|
+
* Updates the Thompson Sampling weight learner based on which signals
|
|
250
|
+
* contributed to the result the user selected (success) or rejected (failure).
|
|
251
|
+
*
|
|
252
|
+
* @param result - The search result receiving feedback.
|
|
253
|
+
* @param success - true = user found it useful, false = irrelevant.
|
|
254
|
+
*/
|
|
255
|
+
recordFeedback(result, success) {
|
|
256
|
+
if (!this.weightLearner) return;
|
|
257
|
+
for (const source of result.sources) {
|
|
258
|
+
this.weightLearner.update(source, success);
|
|
259
|
+
}
|
|
260
|
+
if (result.pramana) {
|
|
261
|
+
this.weightLearner.update("pramana", success);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Perform hybrid search across all enabled rankers.
|
|
266
|
+
*
|
|
267
|
+
* Each ranker produces its own ranking. Results are fused via RRF:
|
|
268
|
+
* score(d) = Σ w_i / (k + rank_i(d))
|
|
269
|
+
*
|
|
270
|
+
* When a HybridWeightLearner is set, w_i are Thompson-sampled weights.
|
|
271
|
+
* Otherwise, all weights are 1.0 (standard RRF).
|
|
272
|
+
*
|
|
273
|
+
* When pramana is enabled, each result receives an additive epistemic boost:
|
|
274
|
+
* finalScore += δ * pramanaReliability(d)
|
|
275
|
+
*
|
|
276
|
+
* @param query - The search query.
|
|
277
|
+
* @param configOverride - Optional per-query config overrides.
|
|
278
|
+
* @returns Fused results sorted by score descending.
|
|
279
|
+
*/
|
|
280
|
+
async search(query, configOverride) {
|
|
281
|
+
const cfg = { ...this.config, ...configOverride };
|
|
282
|
+
const weights = this.weightLearner ? this.weightLearner.sample() : { bm25: 1, vector: 1, graphrag: 1, pramana: 1 };
|
|
283
|
+
const rankings = [];
|
|
284
|
+
const tasks = [];
|
|
285
|
+
if (cfg.enableBM25) {
|
|
286
|
+
tasks.push(
|
|
287
|
+
(async () => {
|
|
288
|
+
const bm25Results = searchSessions(query, cfg.project);
|
|
289
|
+
rankings.push({
|
|
290
|
+
source: "bm25",
|
|
291
|
+
weight: weights.bm25,
|
|
292
|
+
results: bm25Results.map((meta) => ({
|
|
293
|
+
id: meta.id,
|
|
294
|
+
title: meta.title,
|
|
295
|
+
content: `${meta.title} [${meta.tags.join(", ")}] agent:${meta.agent}`
|
|
296
|
+
}))
|
|
297
|
+
});
|
|
298
|
+
})()
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
if (cfg.enableVector && this.recallEngine) {
|
|
302
|
+
tasks.push(
|
|
303
|
+
(async () => {
|
|
304
|
+
try {
|
|
305
|
+
const vectorResults = await this.recallEngine.recall(query, {
|
|
306
|
+
topK: cfg.topK * 2
|
|
307
|
+
// Over-fetch for fusion
|
|
308
|
+
});
|
|
309
|
+
rankings.push({
|
|
310
|
+
source: "vector",
|
|
311
|
+
weight: weights.vector,
|
|
312
|
+
results: vectorResults.map((r) => ({
|
|
313
|
+
id: r.sessionId,
|
|
314
|
+
title: r.title,
|
|
315
|
+
content: r.matchedContent || r.summary
|
|
316
|
+
}))
|
|
317
|
+
});
|
|
318
|
+
} catch {
|
|
319
|
+
}
|
|
320
|
+
})()
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
if (cfg.enableGraphRAG && this.graphEngine) {
|
|
324
|
+
tasks.push(
|
|
325
|
+
(async () => {
|
|
326
|
+
try {
|
|
327
|
+
const graphResults = await this.graphEngine.search(query, void 0, cfg.topK * 2);
|
|
328
|
+
rankings.push({
|
|
329
|
+
source: "graphrag",
|
|
330
|
+
weight: weights.graphrag,
|
|
331
|
+
results: graphResults.map((node) => ({
|
|
332
|
+
id: node.id,
|
|
333
|
+
title: node.label,
|
|
334
|
+
content: node.content
|
|
335
|
+
}))
|
|
336
|
+
});
|
|
337
|
+
} catch {
|
|
338
|
+
}
|
|
339
|
+
})()
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
await Promise.all(tasks);
|
|
343
|
+
if (rankings.length === 0) return [];
|
|
344
|
+
const fusedScores = /* @__PURE__ */ new Map();
|
|
345
|
+
for (const ranking of rankings) {
|
|
346
|
+
for (let rank = 0; rank < ranking.results.length; rank++) {
|
|
347
|
+
const doc = ranking.results[rank];
|
|
348
|
+
const rrfContribution = ranking.weight / (cfg.k + rank);
|
|
349
|
+
const existing = fusedScores.get(doc.id);
|
|
350
|
+
if (existing) {
|
|
351
|
+
existing.score += rrfContribution;
|
|
352
|
+
existing.sources.add(ranking.source);
|
|
353
|
+
existing.ranks[ranking.source] = rank + 1;
|
|
354
|
+
if (doc.content.length > existing.content.length) {
|
|
355
|
+
existing.content = doc.content;
|
|
356
|
+
}
|
|
357
|
+
} else {
|
|
358
|
+
const sources = /* @__PURE__ */ new Set();
|
|
359
|
+
sources.add(ranking.source);
|
|
360
|
+
fusedScores.set(doc.id, {
|
|
361
|
+
id: doc.id,
|
|
362
|
+
title: doc.title,
|
|
363
|
+
content: doc.content,
|
|
364
|
+
score: rrfContribution,
|
|
365
|
+
sources,
|
|
366
|
+
ranks: { [ranking.source]: rank + 1 }
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
for (const entry of fusedScores.values()) {
|
|
372
|
+
if (entry.sources.size >= 3) {
|
|
373
|
+
entry.score *= 1.15;
|
|
374
|
+
} else if (entry.sources.size >= 2) {
|
|
375
|
+
entry.score *= 1.05;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
const pramanaMap = /* @__PURE__ */ new Map();
|
|
379
|
+
if (cfg.enablePramana && this.graphEngine) {
|
|
380
|
+
const docIds = [...fusedScores.keys()];
|
|
381
|
+
const batchPramana = this.graphEngine.lookupPramanaBatch(docIds);
|
|
382
|
+
for (const [id, ptype] of batchPramana) {
|
|
383
|
+
pramanaMap.set(id, ptype);
|
|
384
|
+
}
|
|
385
|
+
const delta = cfg.pramanaWeight * weights.pramana;
|
|
386
|
+
for (const entry of fusedScores.values()) {
|
|
387
|
+
const ptype = pramanaMap.get(entry.id) ?? "shabda";
|
|
388
|
+
const reliability = PRAMANA_RELIABILITY[ptype];
|
|
389
|
+
entry.score += delta * reliability;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (this.kalaChakra) {
|
|
393
|
+
for (const entry of fusedScores.values()) {
|
|
394
|
+
if (entry.timestamp !== void 0) {
|
|
395
|
+
entry.score = this.kalaChakra.boostScore(entry.score, entry.timestamp);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
const sorted = [...fusedScores.values()].filter((r) => r.score >= cfg.minScore).sort((a, b) => b.score - a.score).slice(0, cfg.topK);
|
|
400
|
+
return sorted.map((r) => ({
|
|
401
|
+
id: r.id,
|
|
402
|
+
title: r.title,
|
|
403
|
+
content: r.content,
|
|
404
|
+
sources: [...r.sources],
|
|
405
|
+
score: r.score,
|
|
406
|
+
ranks: {
|
|
407
|
+
bm25: r.ranks.bm25,
|
|
408
|
+
vector: r.ranks.vector,
|
|
409
|
+
graphrag: r.ranks.graphrag
|
|
410
|
+
},
|
|
411
|
+
pramana: pramanaMap.get(r.id),
|
|
412
|
+
timestamp: r.timestamp
|
|
413
|
+
}));
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Self-RAG gated search — only retrieves if the query signals a knowledge gap.
|
|
417
|
+
*
|
|
418
|
+
* @param query - The query to evaluate and optionally search.
|
|
419
|
+
* @returns Results if retrieval was triggered, empty array otherwise.
|
|
420
|
+
*/
|
|
421
|
+
async gatedSearch(query, configOverride) {
|
|
422
|
+
if (!shouldRetrieve(query)) return [];
|
|
423
|
+
return this.search(query, configOverride);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
export {
|
|
428
|
+
PRAMANA_RELIABILITY,
|
|
429
|
+
HybridWeightLearner,
|
|
430
|
+
shouldRetrieve,
|
|
431
|
+
HybridSearchEngine
|
|
432
|
+
};
|
|
433
|
+
//# sourceMappingURL=chunk-KDRROLVN.js.map
|