@relayplane/proxy 1.8.35 → 1.8.38
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/README.md +9 -7
- package/dist/budget.d.ts +39 -0
- package/dist/budget.d.ts.map +1 -1
- package/dist/budget.js +173 -0
- package/dist/budget.js.map +1 -1
- package/dist/config.d.ts +21 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/episode-writer.d.ts +28 -0
- package/dist/episode-writer.d.ts.map +1 -0
- package/dist/episode-writer.js +263 -0
- package/dist/episode-writer.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/osmosis-store.d.ts +9 -1
- package/dist/osmosis-store.d.ts.map +1 -1
- package/dist/osmosis-store.js +93 -4
- package/dist/osmosis-store.js.map +1 -1
- package/dist/session-tracker.d.ts +61 -0
- package/dist/session-tracker.d.ts.map +1 -0
- package/dist/session-tracker.js +268 -0
- package/dist/session-tracker.js.map +1 -0
- package/dist/standalone-proxy.d.ts.map +1 -1
- package/dist/standalone-proxy.js +813 -18
- package/dist/standalone-proxy.js.map +1 -1
- package/dist/tool-router.d.ts +163 -0
- package/dist/tool-router.d.ts.map +1 -0
- package/dist/tool-router.js +528 -0
- package/dist/tool-router.js.map +1 -0
- package/dist/trace-writer.d.ts +155 -0
- package/dist/trace-writer.d.ts.map +1 -0
- package/dist/trace-writer.js +589 -0
- package/dist/trace-writer.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Episode Writer — Phase 2 Session 4: Layered Session Memory
|
|
4
|
+
*
|
|
5
|
+
* Writes episodic events to osmosis.db after each proxied response.
|
|
6
|
+
* Also tracks promotion candidates: when evidence_count >= PROMOTION_THRESHOLD,
|
|
7
|
+
* promotes the pattern to the procedural (mesh) atom store.
|
|
8
|
+
*
|
|
9
|
+
* All writes are fire-and-forget. Never throws.
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.writeEpisode = writeEpisode;
|
|
46
|
+
exports._resetEpisodeWriter = _resetEpisodeWriter;
|
|
47
|
+
const crypto = __importStar(require("node:crypto"));
|
|
48
|
+
const fs = __importStar(require("node:fs"));
|
|
49
|
+
const path = __importStar(require("node:path"));
|
|
50
|
+
const osmosis_store_js_1 = require("./osmosis-store.js");
|
|
51
|
+
const PROMOTION_THRESHOLD = 2;
|
|
52
|
+
const EPISODIC_MAX_ROWS = parseInt(process.env['RELAYPLANE_EPISODIC_MAX_ROWS'] ?? '100000', 10);
|
|
53
|
+
let _writeCounter = 0;
|
|
54
|
+
// ── DB handles ──────────────────────────────────────────────────────────────
|
|
55
|
+
let _osmosisDb = undefined;
|
|
56
|
+
let _meshDb = undefined;
|
|
57
|
+
function getOsmosisDb() {
|
|
58
|
+
if (_osmosisDb !== undefined)
|
|
59
|
+
return _osmosisDb;
|
|
60
|
+
try {
|
|
61
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
62
|
+
const Database = require('better-sqlite3');
|
|
63
|
+
const dir = (0, osmosis_store_js_1.getRelayplaneDir)();
|
|
64
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
65
|
+
const db = new Database(path.join(dir, 'osmosis.db'));
|
|
66
|
+
db.pragma('journal_mode = WAL');
|
|
67
|
+
_osmosisDb = db;
|
|
68
|
+
return db;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
_osmosisDb = null;
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function getMeshDb() {
|
|
76
|
+
if (_meshDb !== undefined)
|
|
77
|
+
return _meshDb;
|
|
78
|
+
try {
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
80
|
+
const Database = require('better-sqlite3');
|
|
81
|
+
const dir = (0, osmosis_store_js_1.getRelayplaneDir)();
|
|
82
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
83
|
+
const db = new Database(path.join(dir, 'mesh.db'));
|
|
84
|
+
db.pragma('journal_mode = WAL');
|
|
85
|
+
// Minimal atoms schema compatible with mesh-core AtomStore
|
|
86
|
+
db.exec(`
|
|
87
|
+
CREATE TABLE IF NOT EXISTS atoms (
|
|
88
|
+
id TEXT PRIMARY KEY,
|
|
89
|
+
type TEXT NOT NULL,
|
|
90
|
+
observation TEXT NOT NULL,
|
|
91
|
+
context TEXT NOT NULL,
|
|
92
|
+
confidence REAL NOT NULL,
|
|
93
|
+
fitness_score REAL NOT NULL,
|
|
94
|
+
trust_tier TEXT NOT NULL DEFAULT 'local',
|
|
95
|
+
source_agent_hash TEXT NOT NULL,
|
|
96
|
+
created_at TEXT NOT NULL,
|
|
97
|
+
updated_at TEXT NOT NULL,
|
|
98
|
+
decay_rate REAL NOT NULL DEFAULT 0.99,
|
|
99
|
+
tool_name TEXT,
|
|
100
|
+
params_hash TEXT,
|
|
101
|
+
outcome TEXT,
|
|
102
|
+
error_signature TEXT,
|
|
103
|
+
latency_ms REAL,
|
|
104
|
+
reliability_score REAL,
|
|
105
|
+
anti_pattern TEXT,
|
|
106
|
+
failure_cluster_size INTEGER,
|
|
107
|
+
error_type TEXT,
|
|
108
|
+
severity TEXT,
|
|
109
|
+
evidence_count INTEGER NOT NULL DEFAULT 1,
|
|
110
|
+
use_count INTEGER NOT NULL DEFAULT 0,
|
|
111
|
+
success_after_use INTEGER NOT NULL DEFAULT 0,
|
|
112
|
+
failure_after_use INTEGER NOT NULL DEFAULT 0,
|
|
113
|
+
last_used TEXT
|
|
114
|
+
);
|
|
115
|
+
CREATE INDEX IF NOT EXISTS idx_atoms_type ON atoms(type);
|
|
116
|
+
CREATE INDEX IF NOT EXISTS idx_atoms_confidence ON atoms(confidence);
|
|
117
|
+
CREATE INDEX IF NOT EXISTS idx_atoms_fitness ON atoms(fitness_score);
|
|
118
|
+
`);
|
|
119
|
+
_meshDb = db;
|
|
120
|
+
return db;
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
_meshDb = null;
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// ── Write episode ─────────────────────────────────────────────────────────────
|
|
128
|
+
/**
|
|
129
|
+
* Write an episodic event record. Fire-and-forget — never throws.
|
|
130
|
+
*/
|
|
131
|
+
function writeEpisode(sessionId, event) {
|
|
132
|
+
try {
|
|
133
|
+
const db = getOsmosisDb();
|
|
134
|
+
if (!db)
|
|
135
|
+
return;
|
|
136
|
+
const id = crypto.randomUUID();
|
|
137
|
+
db.prepare(`
|
|
138
|
+
INSERT OR IGNORE INTO episodic_events
|
|
139
|
+
(id, session_id, event_type, timestamp, duration_ms, model_used,
|
|
140
|
+
tokens_in, tokens_out, cost_usd, outcome, outcome_detail, trace_id)
|
|
141
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
142
|
+
`).run(id, sessionId, event.eventType, Date.now(), event.durationMs ?? null, event.modelUsed, event.tokensIn, event.tokensOut, event.costUsd, event.outcome, event.outcomeDetail ?? null, event.traceId ?? null);
|
|
143
|
+
// Prune episodic_events every 100th write
|
|
144
|
+
_writeCounter++;
|
|
145
|
+
if (_writeCounter % 100 === 0) {
|
|
146
|
+
db.prepare(`
|
|
147
|
+
DELETE FROM episodic_events WHERE id NOT IN (
|
|
148
|
+
SELECT id FROM episodic_events ORDER BY timestamp DESC LIMIT ?
|
|
149
|
+
)
|
|
150
|
+
`).run(EPISODIC_MAX_ROWS);
|
|
151
|
+
}
|
|
152
|
+
// Check promotion after each write
|
|
153
|
+
const signature = computeSignature(event.modelUsed, event.eventType, event.outcome);
|
|
154
|
+
checkPromotion(sessionId, signature);
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// best-effort
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// ── Promotion ─────────────────────────────────────────────────────────────────
|
|
161
|
+
function computeSignature(model, eventType, outcome) {
|
|
162
|
+
return crypto.createHash('sha256')
|
|
163
|
+
.update(`${model}:${eventType}:${outcome}`)
|
|
164
|
+
.digest('hex')
|
|
165
|
+
.slice(0, 32);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Check and potentially promote an episodic pattern to procedural (mesh) store.
|
|
169
|
+
* Fire-and-forget — never throws.
|
|
170
|
+
*/
|
|
171
|
+
function checkPromotion(sessionId, patternSignature) {
|
|
172
|
+
try {
|
|
173
|
+
const db = getOsmosisDb();
|
|
174
|
+
if (!db)
|
|
175
|
+
return;
|
|
176
|
+
const now = Date.now();
|
|
177
|
+
// Check if candidate exists
|
|
178
|
+
const existing = db.prepare(`SELECT id, evidence_count, session_ids, promoted_at FROM episodic_to_procedural_candidates WHERE pattern_signature = ?`).get(patternSignature);
|
|
179
|
+
if (!existing) {
|
|
180
|
+
const id = crypto.randomUUID();
|
|
181
|
+
db.prepare(`
|
|
182
|
+
INSERT OR IGNORE INTO episodic_to_procedural_candidates
|
|
183
|
+
(id, pattern_signature, session_ids, evidence_count, first_seen_at, last_seen_at)
|
|
184
|
+
VALUES (?, ?, ?, 1, ?, ?)
|
|
185
|
+
`).run(id, patternSignature, JSON.stringify([sessionId]), now, now);
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// Update existing candidate
|
|
189
|
+
const sessionIds = (() => {
|
|
190
|
+
try {
|
|
191
|
+
return JSON.parse(existing.session_ids);
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
return [];
|
|
195
|
+
}
|
|
196
|
+
})();
|
|
197
|
+
if (!sessionIds.includes(sessionId))
|
|
198
|
+
sessionIds.push(sessionId);
|
|
199
|
+
db.prepare(`
|
|
200
|
+
UPDATE episodic_to_procedural_candidates
|
|
201
|
+
SET evidence_count = evidence_count + 1,
|
|
202
|
+
last_seen_at = ?,
|
|
203
|
+
session_ids = ?
|
|
204
|
+
WHERE pattern_signature = ?
|
|
205
|
+
`).run(now, JSON.stringify(sessionIds), patternSignature);
|
|
206
|
+
const newCount = existing.evidence_count + 1;
|
|
207
|
+
if (newCount >= PROMOTION_THRESHOLD && !existing.promoted_at) {
|
|
208
|
+
const atomId = promoteToProcedural(patternSignature, newCount);
|
|
209
|
+
if (atomId) {
|
|
210
|
+
db.prepare(`
|
|
211
|
+
UPDATE episodic_to_procedural_candidates
|
|
212
|
+
SET promoted_at = ?, atom_id = ?
|
|
213
|
+
WHERE pattern_signature = ?
|
|
214
|
+
`).run(now, atomId, patternSignature);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
// best-effort
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Write a procedural atom to the mesh db. Returns the atom id or null on failure.
|
|
224
|
+
*/
|
|
225
|
+
function promoteToProcedural(patternSignature, evidenceCount) {
|
|
226
|
+
try {
|
|
227
|
+
const db = getMeshDb();
|
|
228
|
+
if (!db)
|
|
229
|
+
return null;
|
|
230
|
+
const id = crypto.randomUUID();
|
|
231
|
+
const now = new Date().toISOString();
|
|
232
|
+
const confidence = Math.min(1.0, 0.5 + evidenceCount * 0.1);
|
|
233
|
+
const observation = `Recurring pattern observed ${evidenceCount} times (sig: ${patternSignature.slice(0, 8)})`;
|
|
234
|
+
db.prepare(`
|
|
235
|
+
INSERT OR IGNORE INTO atoms
|
|
236
|
+
(id, type, observation, context, confidence, fitness_score, trust_tier,
|
|
237
|
+
source_agent_hash, created_at, updated_at, decay_rate, evidence_count)
|
|
238
|
+
VALUES (?, 'pattern', ?, ?, ?, ?, 'local', ?, ?, ?, 0.99, ?)
|
|
239
|
+
`).run(id, observation, JSON.stringify({ patternSignature, promotedFromEpisodic: true }), confidence, confidence * 0.9, 'relayplane-proxy', now, now, evidenceCount);
|
|
240
|
+
return id;
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/** Exposed for testing — reset singleton db handles. */
|
|
247
|
+
function _resetEpisodeWriter() {
|
|
248
|
+
if (_osmosisDb) {
|
|
249
|
+
try {
|
|
250
|
+
_osmosisDb.close();
|
|
251
|
+
}
|
|
252
|
+
catch { /* ignore */ }
|
|
253
|
+
}
|
|
254
|
+
if (_meshDb) {
|
|
255
|
+
try {
|
|
256
|
+
_meshDb.close();
|
|
257
|
+
}
|
|
258
|
+
catch { /* ignore */ }
|
|
259
|
+
}
|
|
260
|
+
_osmosisDb = undefined;
|
|
261
|
+
_meshDb = undefined;
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=episode-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"episode-writer.js","sourceRoot":"","sources":["../src/episode-writer.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8GH,oCAyCC;AAwGD,kDAKC;AAlQD,oDAAsC;AACtC,4CAA8B;AAC9B,gDAAkC;AAClC,yDAAsD;AAEtD,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,IAAI,QAAQ,EAAE,EAAE,CAAC,CAAC;AAChG,IAAI,aAAa,GAAG,CAAC,CAAC;AAEtB,+EAA+E;AAE/E,IAAI,UAAU,GAAyD,SAAS,CAAC;AACjF,IAAI,OAAO,GAAyD,SAAS,CAAC;AAE9E,SAAS,YAAY;IACnB,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC;IAChD,IAAI,CAAC;QACH,iEAAiE;QACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAoC,CAAC;QAC9E,MAAM,GAAG,GAAG,IAAA,mCAAgB,GAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;QACtD,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAChC,UAAU,GAAG,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,GAAG,IAAI,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IAChB,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC;IAC1C,IAAI,CAAC;QACH,iEAAiE;QACjE,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAoC,CAAC;QAC9E,MAAM,GAAG,GAAG,IAAA,mCAAgB,GAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;QACnD,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAChC,2DAA2D;QAC3D,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgCP,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,IAAI,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAuBD,iFAAiF;AAEjF;;GAEG;AACH,SAAgB,YAAY,CAAC,SAAiB,EAAE,KAAmB;IACjE,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;QAC1B,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/B,EAAE,CAAC,OAAO,CAAC;;;;;KAKV,CAAC,CAAC,GAAG,CACJ,EAAE,EACF,SAAS,EACT,KAAK,CAAC,SAAS,EACf,IAAI,CAAC,GAAG,EAAE,EACV,KAAK,CAAC,UAAU,IAAI,IAAI,EACxB,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,OAAO,EACb,KAAK,CAAC,aAAa,IAAI,IAAI,EAC3B,KAAK,CAAC,OAAO,IAAI,IAAI,CACtB,CAAC;QAEF,0CAA0C;QAC1C,aAAa,EAAE,CAAC;QAChB,IAAI,aAAa,GAAG,GAAG,KAAK,CAAC,EAAE,CAAC;YAC9B,EAAE,CAAC,OAAO,CAAC;;;;OAIV,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC5B,CAAC;QAED,mCAAmC;QACnC,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACpF,cAAc,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;AACH,CAAC;AAED,iFAAiF;AAEjF,SAAS,gBAAgB,CAAC,KAAa,EAAE,SAAiB,EAAE,OAAe;IACzE,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;SAC/B,MAAM,CAAC,GAAG,KAAK,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;SAC1C,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,SAAiB,EAAE,gBAAwB;IACjE,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;QAC1B,IAAI,CAAC,EAAE;YAAE,OAAO;QAEhB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEvB,4BAA4B;QAC5B,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CACzB,wHAAwH,CACzH,CAAC,GAAG,CAAC,gBAAgB,CAAwG,CAAC;QAE/H,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;YAC/B,EAAE,CAAC,OAAO,CAAC;;;;OAIV,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;YACpE,OAAO;QACT,CAAC;QAED,4BAA4B;QAC5B,MAAM,UAAU,GAAa,CAAC,GAAG,EAAE;YACjC,IAAI,CAAC;gBAAC,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAa,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,OAAO,EAAE,CAAC;YAAC,CAAC;QACnF,CAAC,CAAC,EAAE,CAAC;QACL,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEhE,EAAE,CAAC,OAAO,CAAC;;;;;;KAMV,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC,CAAC;QAE1D,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,GAAG,CAAC,CAAC;QAC7C,IAAI,QAAQ,IAAI,mBAAmB,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;YAC7D,MAAM,MAAM,GAAG,mBAAmB,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;YAC/D,IAAI,MAAM,EAAE,CAAC;gBACX,EAAE,CAAC,OAAO,CAAC;;;;SAIV,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,gBAAwB,EAAE,aAAqB;IAC1E,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;QACvB,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAErB,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,aAAa,GAAG,GAAG,CAAC,CAAC;QAC5D,MAAM,WAAW,GAAG,8BAA8B,aAAa,gBAAgB,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC;QAE/G,EAAE,CAAC,OAAO,CAAC;;;;;KAKV,CAAC,CAAC,GAAG,CACJ,EAAE,EACF,WAAW,EACX,IAAI,CAAC,SAAS,CAAC,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC,EAChE,UAAU,EACV,UAAU,GAAG,GAAG,EAChB,kBAAkB,EAClB,GAAG,EACH,GAAG,EACH,aAAa,CACd,CAAC;QAEF,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,wDAAwD;AACxD,SAAgB,mBAAmB;IACjC,IAAI,UAAU,EAAE,CAAC;QAAC,IAAI,CAAC;YAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAAC,CAAC;IACtE,IAAI,OAAO,EAAE,CAAC;QAAC,IAAI,CAAC;YAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAAC,CAAC;IAChE,UAAU,GAAG,SAAS,CAAC;IACvB,OAAO,GAAG,SAAS,CAAC;AACtB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -43,4 +43,6 @@ export { RecoveryEngine, RecoveryPatternStore, FailureObserver, PatternApplicato
|
|
|
43
43
|
export type { RecoveryConfig, RecoveryPattern, RecoveryPatternType, RecoveryResult, RecoveryEvent, FailureContext, RequestOverrides, } from './recovery.js';
|
|
44
44
|
export { ProxyServer, createProxyServer, createSandboxedProxyServer } from './server.js';
|
|
45
45
|
export type { ProxyServerConfig } from './server.js';
|
|
46
|
+
export { ToolRouter, getToolRouter, resetToolRouter, extractToolContext, BUILTIN_PACKS, DEFAULT_TOOL_ROUTER_CONFIG, } from './tool-router.js';
|
|
47
|
+
export type { ToolEntry, ToolPack, ToolRateLimit, AgentAuthConfig, ToolAuthContext, ToolAuthResult, ToolRouterConfig, ToolSchema, RateLimitCheckResult, } from './tool-router.js';
|
|
46
48
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EACL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,SAAS,EACT,YAAY,EACZ,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGnE,OAAO,EACL,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,eAAe,EACf,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAGrB,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG3D,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzF,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,EACL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,SAAS,EACT,YAAY,EACZ,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGnE,OAAO,EACL,eAAe,EACf,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,eAAe,EACf,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,aAAa,CAAC;AAGrB,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAG3D,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzF,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGrD,OAAO,EACL,UAAU,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,0BAA0B,GAC3B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,SAAS,EACT,QAAQ,EACR,aAAa,EACb,eAAe,EACf,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,oBAAoB,GACrB,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
22
|
exports.mapCloudModelToOllama = exports.convertOllamaStreamChunk = exports.convertOllamaResponse = exports.buildOllamaRequest = exports.convertMessagesToOllama = exports.forwardToOllamaStream = exports.forwardToOllama = exports.resolveOllamaModel = exports.shouldRouteToOllama = exports.clearOllamaHealthCache = exports.checkOllamaHealthCached = exports.checkOllamaHealth = exports.proxyStatsCollector = exports.defaultLogger = exports.resolveConfig = exports.StatusReporter = exports.StatsCollector = exports.probeHealth = exports.handleHealthRequest = exports.ProcessManager = exports.RelayPlaneMiddleware = exports.CircuitBreaker = exports.printTelemetryDisclosure = exports.getTelemetryPath = exports.clearTelemetry = exports.getTelemetryStats = exports.getLocalTelemetry = exports.clearAuditBuffer = exports.getAuditBuffer = exports.isOfflineMode = exports.setOfflineMode = exports.isAuditMode = exports.setAuditMode = exports.estimateCost = exports.inferTaskType = exports.recordTelemetry = exports.getConfigPath = exports.getConfigDir = exports.getApiKey = exports.setApiKey = exports.getDeviceId = exports.disableTelemetry = exports.enableTelemetry = exports.isTelemetryEnabled = exports.markFirstRunComplete = exports.isFirstRun = exports.updateConfig = exports.saveConfig = exports.loadConfig = exports.startProxy = void 0;
|
|
23
|
-
exports.createSandboxedProxyServer = exports.createProxyServer = exports.ProxyServer = exports.PatternApplicator = exports.FailureObserver = exports.RecoveryPatternStore = exports.RecoveryEngine = exports.CLOUD_TO_OLLAMA_MODEL_MAP = exports.OLLAMA_DEFAULTS = void 0;
|
|
23
|
+
exports.DEFAULT_TOOL_ROUTER_CONFIG = exports.BUILTIN_PACKS = exports.extractToolContext = exports.resetToolRouter = exports.getToolRouter = exports.ToolRouter = exports.createSandboxedProxyServer = exports.createProxyServer = exports.ProxyServer = exports.PatternApplicator = exports.FailureObserver = exports.RecoveryPatternStore = exports.RecoveryEngine = exports.CLOUD_TO_OLLAMA_MODEL_MAP = exports.OLLAMA_DEFAULTS = void 0;
|
|
24
24
|
// Standalone proxy (requires only @relayplane/core)
|
|
25
25
|
var standalone_proxy_js_1 = require("./standalone-proxy.js");
|
|
26
26
|
Object.defineProperty(exports, "startProxy", { enumerable: true, get: function () { return standalone_proxy_js_1.startProxy; } });
|
|
@@ -103,4 +103,12 @@ var server_js_1 = require("./server.js");
|
|
|
103
103
|
Object.defineProperty(exports, "ProxyServer", { enumerable: true, get: function () { return server_js_1.ProxyServer; } });
|
|
104
104
|
Object.defineProperty(exports, "createProxyServer", { enumerable: true, get: function () { return server_js_1.createProxyServer; } });
|
|
105
105
|
Object.defineProperty(exports, "createSandboxedProxyServer", { enumerable: true, get: function () { return server_js_1.createSandboxedProxyServer; } });
|
|
106
|
+
// Tool Router — deny-by-default tool authorization (Phase 2, Session 3)
|
|
107
|
+
var tool_router_js_1 = require("./tool-router.js");
|
|
108
|
+
Object.defineProperty(exports, "ToolRouter", { enumerable: true, get: function () { return tool_router_js_1.ToolRouter; } });
|
|
109
|
+
Object.defineProperty(exports, "getToolRouter", { enumerable: true, get: function () { return tool_router_js_1.getToolRouter; } });
|
|
110
|
+
Object.defineProperty(exports, "resetToolRouter", { enumerable: true, get: function () { return tool_router_js_1.resetToolRouter; } });
|
|
111
|
+
Object.defineProperty(exports, "extractToolContext", { enumerable: true, get: function () { return tool_router_js_1.extractToolContext; } });
|
|
112
|
+
Object.defineProperty(exports, "BUILTIN_PACKS", { enumerable: true, get: function () { return tool_router_js_1.BUILTIN_PACKS; } });
|
|
113
|
+
Object.defineProperty(exports, "DEFAULT_TOOL_ROUTER_CONFIG", { enumerable: true, get: function () { return tool_router_js_1.DEFAULT_TOOL_ROUTER_CONFIG; } });
|
|
106
114
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;;AAEH,oDAAoD;AACpD,6DAAmD;AAA1C,iHAAA,UAAU,OAAA;AAGnB,gBAAgB;AAChB,yCAcqB;AAbnB,uGAAA,UAAU,OAAA;AACV,uGAAA,UAAU,OAAA;AACV,yGAAA,YAAY,OAAA;AACZ,uGAAA,UAAU,OAAA;AACV,iHAAA,oBAAoB,OAAA;AACpB,+GAAA,kBAAkB,OAAA;AAClB,4GAAA,eAAe,OAAA;AACf,6GAAA,gBAAgB,OAAA;AAChB,wGAAA,WAAW,OAAA;AACX,sGAAA,SAAS,OAAA;AACT,sGAAA,SAAS,OAAA;AACT,yGAAA,YAAY,OAAA;AACZ,0GAAA,aAAa,OAAA;AAIf,YAAY;AACZ,+CAewB;AAdtB,+GAAA,eAAe,OAAA;AACf,6GAAA,aAAa,OAAA;AACb,4GAAA,YAAY,OAAA;AACZ,4GAAA,YAAY,OAAA;AACZ,2GAAA,WAAW,OAAA;AACX,8GAAA,cAAc,OAAA;AACd,6GAAA,aAAa,OAAA;AACb,8GAAA,cAAc,OAAA;AACd,gHAAA,gBAAgB,OAAA;AAChB,iHAAA,iBAAiB,OAAA;AACjB,iHAAA,iBAAiB,OAAA;AACjB,8GAAA,cAAc,OAAA;AACd,gHAAA,gBAAgB,OAAA;AAChB,wHAAA,wBAAwB,OAAA;AAI1B,iCAAiC;AACjC,2DAAoE;AAA3D,oHAAA,cAAc,OAAA;AACvB,iDAAuD;AAA9C,qHAAA,oBAAoB,OAAA;AAE7B,2DAAsD;AAA7C,oHAAA,cAAc,OAAA;AACvB,yCAA+D;AAAtD,gHAAA,mBAAmB,OAAA;AAAE,wGAAA,WAAW,OAAA;AACzC,uCAA4C;AAAnC,0GAAA,cAAc,OAAA;AACvB,yCAA6C;AAApC,2GAAA,cAAc,OAAA;AAEvB,qDAAkD;AAAzC,gHAAA,aAAa,OAAA;AAEtB,yCAA4C;AAAnC,0GAAA,aAAa,OAAA;AAGtB,gDAAgD;AAChD,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAE5B,8BAA8B;AAC9B,yCAeqB;AAdnB,8GAAA,iBAAiB,OAAA;AACjB,oHAAA,uBAAuB,OAAA;AACvB,mHAAA,sBAAsB,OAAA;AACtB,gHAAA,mBAAmB,OAAA;AACnB,+GAAA,kBAAkB,OAAA;AAClB,4GAAA,eAAe,OAAA;AACf,kHAAA,qBAAqB,OAAA;AACrB,oHAAA,uBAAuB,OAAA;AACvB,+GAAA,kBAAkB,OAAA;AAClB,kHAAA,qBAAqB,OAAA;AACrB,qHAAA,wBAAwB,OAAA;AACxB,kHAAA,qBAAqB,OAAA;AACrB,4GAAA,eAAe,OAAA;AACf,sHAAA,yBAAyB,OAAA;AAU3B,uCAAuC;AACvC,6CAKuB;AAJrB,6GAAA,cAAc,OAAA;AACd,mHAAA,oBAAoB,OAAA;AACpB,8GAAA,eAAe,OAAA;AACf,gHAAA,iBAAiB,OAAA;AAYnB,mFAAmF;AACnF,yCAAyF;AAAhF,wGAAA,WAAW,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAAE,uHAAA,0BAA0B,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;;AAEH,oDAAoD;AACpD,6DAAmD;AAA1C,iHAAA,UAAU,OAAA;AAGnB,gBAAgB;AAChB,yCAcqB;AAbnB,uGAAA,UAAU,OAAA;AACV,uGAAA,UAAU,OAAA;AACV,yGAAA,YAAY,OAAA;AACZ,uGAAA,UAAU,OAAA;AACV,iHAAA,oBAAoB,OAAA;AACpB,+GAAA,kBAAkB,OAAA;AAClB,4GAAA,eAAe,OAAA;AACf,6GAAA,gBAAgB,OAAA;AAChB,wGAAA,WAAW,OAAA;AACX,sGAAA,SAAS,OAAA;AACT,sGAAA,SAAS,OAAA;AACT,yGAAA,YAAY,OAAA;AACZ,0GAAA,aAAa,OAAA;AAIf,YAAY;AACZ,+CAewB;AAdtB,+GAAA,eAAe,OAAA;AACf,6GAAA,aAAa,OAAA;AACb,4GAAA,YAAY,OAAA;AACZ,4GAAA,YAAY,OAAA;AACZ,2GAAA,WAAW,OAAA;AACX,8GAAA,cAAc,OAAA;AACd,6GAAA,aAAa,OAAA;AACb,8GAAA,cAAc,OAAA;AACd,gHAAA,gBAAgB,OAAA;AAChB,iHAAA,iBAAiB,OAAA;AACjB,iHAAA,iBAAiB,OAAA;AACjB,8GAAA,cAAc,OAAA;AACd,gHAAA,gBAAgB,OAAA;AAChB,wHAAA,wBAAwB,OAAA;AAI1B,iCAAiC;AACjC,2DAAoE;AAA3D,oHAAA,cAAc,OAAA;AACvB,iDAAuD;AAA9C,qHAAA,oBAAoB,OAAA;AAE7B,2DAAsD;AAA7C,oHAAA,cAAc,OAAA;AACvB,yCAA+D;AAAtD,gHAAA,mBAAmB,OAAA;AAAE,wGAAA,WAAW,OAAA;AACzC,uCAA4C;AAAnC,0GAAA,cAAc,OAAA;AACvB,yCAA6C;AAApC,2GAAA,cAAc,OAAA;AAEvB,qDAAkD;AAAzC,gHAAA,aAAa,OAAA;AAEtB,yCAA4C;AAAnC,0GAAA,aAAa,OAAA;AAGtB,gDAAgD;AAChD,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA;AAE5B,8BAA8B;AAC9B,yCAeqB;AAdnB,8GAAA,iBAAiB,OAAA;AACjB,oHAAA,uBAAuB,OAAA;AACvB,mHAAA,sBAAsB,OAAA;AACtB,gHAAA,mBAAmB,OAAA;AACnB,+GAAA,kBAAkB,OAAA;AAClB,4GAAA,eAAe,OAAA;AACf,kHAAA,qBAAqB,OAAA;AACrB,oHAAA,uBAAuB,OAAA;AACvB,+GAAA,kBAAkB,OAAA;AAClB,kHAAA,qBAAqB,OAAA;AACrB,qHAAA,wBAAwB,OAAA;AACxB,kHAAA,qBAAqB,OAAA;AACrB,4GAAA,eAAe,OAAA;AACf,sHAAA,yBAAyB,OAAA;AAU3B,uCAAuC;AACvC,6CAKuB;AAJrB,6GAAA,cAAc,OAAA;AACd,mHAAA,oBAAoB,OAAA;AACpB,8GAAA,eAAe,OAAA;AACf,gHAAA,iBAAiB,OAAA;AAYnB,mFAAmF;AACnF,yCAAyF;AAAhF,wGAAA,WAAW,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAAE,uHAAA,0BAA0B,OAAA;AAGnE,wEAAwE;AACxE,mDAO0B;AANxB,4GAAA,UAAU,OAAA;AACV,+GAAA,aAAa,OAAA;AACb,iHAAA,eAAe,OAAA;AACf,oHAAA,kBAAkB,OAAA;AAClB,+GAAA,aAAa,OAAA;AACb,4HAAA,0BAA0B,OAAA"}
|
package/dist/osmosis-store.d.ts
CHANGED
|
@@ -23,11 +23,19 @@ export interface FailureAtom {
|
|
|
23
23
|
timestamp: number;
|
|
24
24
|
}
|
|
25
25
|
export type KnowledgeAtom = SuccessAtom | FailureAtom;
|
|
26
|
+
export declare function getRelayplaneDir(): string;
|
|
27
|
+
/** Exposed for use by episode-writer and memory endpoints. */
|
|
28
|
+
export declare function getOsmosisDb(): import('better-sqlite3').Database | null;
|
|
29
|
+
/** Count knowledge atoms relevant to a session (or all atoms if no session). */
|
|
30
|
+
export declare function countAtomsForSession(sessionId?: string | null): number;
|
|
26
31
|
/**
|
|
27
32
|
* Capture a KnowledgeAtom (fire-and-forget).
|
|
28
33
|
* Never throws. Writes to SQLite; falls back to JSONL.
|
|
34
|
+
*
|
|
35
|
+
* @param atom - The knowledge atom to capture.
|
|
36
|
+
* @param sessionId - Optional session ID to associate with this atom.
|
|
29
37
|
*/
|
|
30
|
-
export declare function captureAtom(atom: KnowledgeAtom): void;
|
|
38
|
+
export declare function captureAtom(atom: KnowledgeAtom, sessionId?: string): void;
|
|
31
39
|
/** Exposed for testing — reset singleton state. */
|
|
32
40
|
export declare function _resetStore(): void;
|
|
33
41
|
//# sourceMappingURL=osmosis-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"osmosis-store.d.ts","sourceRoot":"","sources":["../src/osmosis-store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"osmosis-store.d.ts","sourceRoot":"","sources":["../src/osmosis-store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,WAAW,CAAC;AAoEtD,wBAAgB,gBAAgB,IAAI,MAAM,CAKzC;AAwCD,8DAA8D;AAC9D,wBAAgB,YAAY,IAAI,OAAO,gBAAgB,EAAE,QAAQ,GAAG,IAAI,CAEvE;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAatE;AAkBD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,aAAa,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAgDzE;AAED,mDAAmD;AACnD,wBAAgB,WAAW,IAAI,IAAI,CAOlC"}
|
package/dist/osmosis-store.js
CHANGED
|
@@ -41,6 +41,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
41
41
|
};
|
|
42
42
|
})();
|
|
43
43
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.getRelayplaneDir = getRelayplaneDir;
|
|
45
|
+
exports.getOsmosisDb = getOsmosisDb;
|
|
46
|
+
exports.countAtomsForSession = countAtomsForSession;
|
|
44
47
|
exports.captureAtom = captureAtom;
|
|
45
48
|
exports._resetStore = _resetStore;
|
|
46
49
|
const fs = __importStar(require("node:fs"));
|
|
@@ -57,9 +60,54 @@ CREATE TABLE IF NOT EXISTS knowledge_atoms (
|
|
|
57
60
|
output_tokens INTEGER,
|
|
58
61
|
error_type TEXT,
|
|
59
62
|
fallback_taken INTEGER,
|
|
60
|
-
timestamp INTEGER NOT NULL
|
|
63
|
+
timestamp INTEGER NOT NULL,
|
|
64
|
+
session_id TEXT,
|
|
65
|
+
confidence REAL DEFAULT 0.5,
|
|
66
|
+
observation_count INTEGER DEFAULT 1,
|
|
67
|
+
decay_rate REAL DEFAULT 0.05,
|
|
68
|
+
tags TEXT DEFAULT '[]'
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
CREATE TABLE IF NOT EXISTS episodic_events (
|
|
72
|
+
id TEXT PRIMARY KEY,
|
|
73
|
+
session_id TEXT NOT NULL,
|
|
74
|
+
event_type TEXT NOT NULL,
|
|
75
|
+
timestamp INTEGER NOT NULL,
|
|
76
|
+
duration_ms INTEGER,
|
|
77
|
+
model_used TEXT,
|
|
78
|
+
tokens_in INTEGER,
|
|
79
|
+
tokens_out INTEGER,
|
|
80
|
+
cost_usd REAL,
|
|
81
|
+
tool_name TEXT,
|
|
82
|
+
tool_input_hash TEXT,
|
|
83
|
+
outcome TEXT NOT NULL,
|
|
84
|
+
outcome_detail TEXT,
|
|
85
|
+
trace_id TEXT,
|
|
86
|
+
tags TEXT DEFAULT '[]'
|
|
87
|
+
);
|
|
88
|
+
CREATE INDEX IF NOT EXISTS idx_episodic_session ON episodic_events(session_id);
|
|
89
|
+
CREATE INDEX IF NOT EXISTS idx_episodic_timestamp ON episodic_events(timestamp);
|
|
90
|
+
|
|
91
|
+
CREATE TABLE IF NOT EXISTS episodic_to_procedural_candidates (
|
|
92
|
+
id TEXT PRIMARY KEY,
|
|
93
|
+
pattern_signature TEXT NOT NULL UNIQUE,
|
|
94
|
+
session_ids TEXT DEFAULT '[]',
|
|
95
|
+
evidence_count INTEGER DEFAULT 1,
|
|
96
|
+
first_seen_at INTEGER NOT NULL,
|
|
97
|
+
last_seen_at INTEGER NOT NULL,
|
|
98
|
+
promoted_at INTEGER,
|
|
99
|
+
atom_id TEXT
|
|
61
100
|
);
|
|
62
101
|
`;
|
|
102
|
+
// Migrations for pre-existing DBs that lack newer columns.
|
|
103
|
+
// SQLite does not support IF NOT EXISTS for ADD COLUMN; we catch errors silently.
|
|
104
|
+
const COLUMN_MIGRATIONS = [
|
|
105
|
+
`ALTER TABLE knowledge_atoms ADD COLUMN session_id TEXT`,
|
|
106
|
+
`ALTER TABLE knowledge_atoms ADD COLUMN confidence REAL DEFAULT 0.5`,
|
|
107
|
+
`ALTER TABLE knowledge_atoms ADD COLUMN observation_count INTEGER DEFAULT 1`,
|
|
108
|
+
`ALTER TABLE knowledge_atoms ADD COLUMN decay_rate REAL DEFAULT 0.05`,
|
|
109
|
+
`ALTER TABLE knowledge_atoms ADD COLUMN tags TEXT DEFAULT '[]'`,
|
|
110
|
+
];
|
|
63
111
|
/** Lazy-initialised SQLite database handle, or null if unavailable. */
|
|
64
112
|
let _db = undefined;
|
|
65
113
|
let _jsonlPath = null;
|
|
@@ -83,6 +131,13 @@ function initDb() {
|
|
|
83
131
|
const db = new Database(dbPath);
|
|
84
132
|
db.pragma('journal_mode = WAL');
|
|
85
133
|
db.exec(SCHEMA_SQL);
|
|
134
|
+
// Column migrations for pre-existing DBs — errors are swallowed (column already exists).
|
|
135
|
+
for (const sql of COLUMN_MIGRATIONS) {
|
|
136
|
+
try {
|
|
137
|
+
db.exec(sql);
|
|
138
|
+
}
|
|
139
|
+
catch { /* column already exists */ }
|
|
140
|
+
}
|
|
86
141
|
return db;
|
|
87
142
|
}
|
|
88
143
|
catch {
|
|
@@ -96,13 +151,34 @@ function getDb() {
|
|
|
96
151
|
if (_db) {
|
|
97
152
|
_insertStmt = _db.prepare(`
|
|
98
153
|
INSERT INTO knowledge_atoms
|
|
99
|
-
(type, model, task_type, latency_ms, input_tokens, output_tokens, error_type, fallback_taken, timestamp)
|
|
154
|
+
(type, model, task_type, latency_ms, input_tokens, output_tokens, error_type, fallback_taken, timestamp, session_id)
|
|
100
155
|
VALUES
|
|
101
|
-
(@type, @model, @task_type, @latency_ms, @input_tokens, @output_tokens, @error_type, @fallback_taken, @timestamp)
|
|
156
|
+
(@type, @model, @task_type, @latency_ms, @input_tokens, @output_tokens, @error_type, @fallback_taken, @timestamp, @session_id)
|
|
102
157
|
`);
|
|
103
158
|
}
|
|
104
159
|
return _db;
|
|
105
160
|
}
|
|
161
|
+
/** Exposed for use by episode-writer and memory endpoints. */
|
|
162
|
+
function getOsmosisDb() {
|
|
163
|
+
return getDb();
|
|
164
|
+
}
|
|
165
|
+
/** Count knowledge atoms relevant to a session (or all atoms if no session). */
|
|
166
|
+
function countAtomsForSession(sessionId) {
|
|
167
|
+
try {
|
|
168
|
+
const db = getDb();
|
|
169
|
+
if (!db)
|
|
170
|
+
return 0;
|
|
171
|
+
if (sessionId) {
|
|
172
|
+
const row = db.prepare(`SELECT COUNT(*) as cnt FROM knowledge_atoms WHERE session_id = ?`).get(sessionId);
|
|
173
|
+
return row?.cnt ?? 0;
|
|
174
|
+
}
|
|
175
|
+
const row = db.prepare(`SELECT COUNT(*) as cnt FROM knowledge_atoms`).get();
|
|
176
|
+
return row?.cnt ?? 0;
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
return 0;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
106
182
|
function getJsonlPath() {
|
|
107
183
|
if (_jsonlPath)
|
|
108
184
|
return _jsonlPath;
|
|
@@ -122,8 +198,11 @@ function writeToJsonl(atom) {
|
|
|
122
198
|
/**
|
|
123
199
|
* Capture a KnowledgeAtom (fire-and-forget).
|
|
124
200
|
* Never throws. Writes to SQLite; falls back to JSONL.
|
|
201
|
+
*
|
|
202
|
+
* @param atom - The knowledge atom to capture.
|
|
203
|
+
* @param sessionId - Optional session ID to associate with this atom.
|
|
125
204
|
*/
|
|
126
|
-
function captureAtom(atom) {
|
|
205
|
+
function captureAtom(atom, sessionId) {
|
|
127
206
|
try {
|
|
128
207
|
const db = getDb();
|
|
129
208
|
if (db && _insertStmt) {
|
|
@@ -138,7 +217,16 @@ function captureAtom(atom) {
|
|
|
138
217
|
error_type: null,
|
|
139
218
|
fallback_taken: null,
|
|
140
219
|
timestamp: atom.timestamp,
|
|
220
|
+
session_id: sessionId ?? null,
|
|
141
221
|
});
|
|
222
|
+
// Update confidence on repeat observations for same (model, task_type).
|
|
223
|
+
if (atom.model && atom.taskType) {
|
|
224
|
+
try {
|
|
225
|
+
db.prepare(`UPDATE knowledge_atoms SET observation_count = observation_count + 1, confidence = MIN(1.0, confidence + 0.1)
|
|
226
|
+
WHERE type = 'success' AND model = ? AND task_type = ? AND id != last_insert_rowid()`).run(atom.model, atom.taskType);
|
|
227
|
+
}
|
|
228
|
+
catch { /* best-effort */ }
|
|
229
|
+
}
|
|
142
230
|
}
|
|
143
231
|
else {
|
|
144
232
|
_insertStmt.run({
|
|
@@ -151,6 +239,7 @@ function captureAtom(atom) {
|
|
|
151
239
|
error_type: atom.errorType ?? null,
|
|
152
240
|
fallback_taken: atom.fallbackTaken ? 1 : 0,
|
|
153
241
|
timestamp: atom.timestamp,
|
|
242
|
+
session_id: sessionId ?? null,
|
|
154
243
|
});
|
|
155
244
|
}
|
|
156
245
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"osmosis-store.js","sourceRoot":"","sources":["../src/osmosis-store.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"osmosis-store.js","sourceRoot":"","sources":["../src/osmosis-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Intelligence — X-Claude-Code-Session-Id tracking
|
|
3
|
+
*
|
|
4
|
+
* Stores per-session aggregates in ~/.relayplane/sessions.db (SQLite via better-sqlite3).
|
|
5
|
+
* Falls back to an in-memory Map if SQLite is unavailable (e.g. no native bindings).
|
|
6
|
+
*
|
|
7
|
+
* Extracts the X-Claude-Code-Session-Id header from every request;
|
|
8
|
+
* if missing, synthesises a session ID from sha256(hour + model).slice(0,16)
|
|
9
|
+
* prefixed with "syn_".
|
|
10
|
+
*
|
|
11
|
+
* All writes are fire-and-forget; errors are silently swallowed.
|
|
12
|
+
*/
|
|
13
|
+
import type * as http from 'node:http';
|
|
14
|
+
export interface SessionEntry {
|
|
15
|
+
id: string;
|
|
16
|
+
started_at: number;
|
|
17
|
+
last_seen_at: number;
|
|
18
|
+
total_cost_usd: number;
|
|
19
|
+
total_tokens_in: number;
|
|
20
|
+
total_tokens_out: number;
|
|
21
|
+
request_count: number;
|
|
22
|
+
session_source: 'claude-code' | 'synthetic';
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Extract or synthesise a session ID from an incoming HTTP request.
|
|
26
|
+
*
|
|
27
|
+
* - If the X-Claude-Code-Session-Id header is present, use it (source = 'claude-code').
|
|
28
|
+
* - Otherwise, generate a synthetic ID: sha256(`${hourBucket}:${model}`).slice(0,16)
|
|
29
|
+
* prefixed with "syn_" (source = 'synthetic').
|
|
30
|
+
*/
|
|
31
|
+
export declare function getSessionId(req: Pick<http.IncomingMessage, 'headers'>, model?: string): {
|
|
32
|
+
sessionId: string;
|
|
33
|
+
sessionSource: 'claude-code' | 'synthetic';
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Upsert a session record, accumulating cost and token counts.
|
|
37
|
+
* Fire-and-forget; never throws. Falls back to in-memory store if SQLite unavailable.
|
|
38
|
+
*/
|
|
39
|
+
export declare function upsertSession(sessionId: string, sessionSource: 'claude-code' | 'synthetic', costUsd: number, tokensIn: number, tokensOut: number): void;
|
|
40
|
+
export interface SessionQueryOptions {
|
|
41
|
+
limit?: number;
|
|
42
|
+
days?: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Query sessions from the last N days, most-recent first, paginated.
|
|
46
|
+
* Falls back to in-memory store if SQLite unavailable.
|
|
47
|
+
*/
|
|
48
|
+
export declare function getSessions(options?: SessionQueryOptions): SessionEntry[];
|
|
49
|
+
/**
|
|
50
|
+
* Return sessions active in the last 5 minutes.
|
|
51
|
+
* Falls back to in-memory store if SQLite unavailable.
|
|
52
|
+
*/
|
|
53
|
+
export declare function getActiveSessions(): SessionEntry[];
|
|
54
|
+
/**
|
|
55
|
+
* Mark stale sessions complete — staleness is computed dynamically via
|
|
56
|
+
* last_seen_at filters, so this is a no-op exposed for API symmetry.
|
|
57
|
+
*/
|
|
58
|
+
export declare function markStaleSessionsComplete(): void;
|
|
59
|
+
/** Exposed for testing — reset singleton state. */
|
|
60
|
+
export declare function _resetStore(): void;
|
|
61
|
+
//# sourceMappingURL=session-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-tracker.d.ts","sourceRoot":"","sources":["../src/session-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,KAAK,IAAI,MAAM,WAAW,CAAC;AAEvC,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,aAAa,GAAG,WAAW,CAAC;CAC7C;AAoED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,EAC1C,KAAK,CAAC,EAAE,MAAM,GACb;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,aAAa,GAAG,WAAW,CAAA;CAAE,CAoBnE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,aAAa,GAAG,WAAW,EAC1C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,IAAI,CAwCN;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,GAAE,mBAAwB,GAAG,YAAY,EAAE,CA4B7E;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,YAAY,EAAE,CAwBlD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAED,mDAAmD;AACnD,wBAAgB,WAAW,IAAI,IAAI,CAWlC"}
|