lynkr 9.7.2 → 9.9.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/README.md +29 -19
- package/bin/cli.js +11 -0
- package/bin/lynkr-init.js +14 -1
- package/bin/lynkr-usage.js +78 -0
- package/bin/wrap.js +60 -35
- package/config/difficulty-anchors.json +22 -0
- package/package.json +24 -3
- package/scripts/audit-log-reader.js +399 -0
- package/scripts/calibrate-thresholds.js +38 -157
- package/scripts/compact-dictionary.js +204 -0
- package/scripts/test-deduplication.js +448 -0
- package/scripts/ws7-anchor-replay.js +108 -0
- package/skills/lynkr/SKILL.md +195 -0
- package/src/agents/context-manager.js +18 -2
- package/src/agents/definitions/loader.js +90 -0
- package/src/agents/executor.js +24 -2
- package/src/agents/index.js +9 -1
- package/src/agents/parallel-coordinator.js +2 -2
- package/src/agents/reflector.js +11 -1
- package/src/api/middleware/loop-guard.js +87 -0
- package/src/api/middleware/request-logging.js +5 -64
- package/src/api/middleware/session.js +0 -0
- package/src/api/openai-router.js +120 -101
- package/src/api/providers-handler.js +27 -2
- package/src/api/router.js +450 -125
- package/src/budget/index.js +2 -19
- package/src/cache/semantic.js +9 -0
- package/src/clients/databricks.js +459 -146
- package/src/clients/gpt-utils.js +11 -105
- package/src/clients/openai-format.js +10 -3
- package/src/clients/openrouter-utils.js +49 -24
- package/src/clients/prompt-cache-injection.js +1 -0
- package/src/clients/provider-capabilities.js +1 -1
- package/src/clients/responses-format.js +34 -3
- package/src/clients/routing.js +15 -0
- package/src/config/index.js +36 -2
- package/src/context/gcf.js +275 -0
- package/src/context/tool-result-compressor.js +51 -9
- package/src/dashboard/api.js +1 -0
- package/src/logger/index.js +14 -1
- package/src/memory/search.js +12 -40
- package/src/memory/tools.js +3 -24
- package/src/orchestrator/bypass.js +4 -2
- package/src/orchestrator/index.js +144 -88
- package/src/routing/affinity-store.js +194 -0
- package/src/routing/agentic-detector.js +36 -6
- package/src/routing/bandit.js +25 -6
- package/src/routing/calibration.js +212 -0
- package/src/routing/client-profiles.js +292 -0
- package/src/routing/complexity-analyzer.js +48 -11
- package/src/routing/deescalator.js +148 -0
- package/src/routing/degradation.js +109 -0
- package/src/routing/feedback.js +157 -0
- package/src/routing/index.js +897 -87
- package/src/routing/intent-score.js +339 -0
- package/src/routing/interaction.js +3 -0
- package/src/routing/knn-router.js +70 -21
- package/src/routing/model-registry.js +28 -7
- package/src/routing/model-tiers.js +25 -2
- package/src/routing/reward-pipeline.js +68 -2
- package/src/routing/risk-analyzer.js +30 -1
- package/src/routing/risk-classifier.js +6 -2
- package/src/routing/session-affinity.js +162 -34
- package/src/routing/telemetry.js +298 -10
- package/src/routing/verifier.js +267 -0
- package/src/server.js +66 -21
- package/src/sessions/cleanup.js +17 -0
- package/src/tools/index.js +1 -15
- package/src/tools/smart-selection.js +10 -0
- package/src/tools/web-client.js +3 -3
- package/.eslintrc.cjs +0 -12
- package/benchmark-configs/litellm_config.yaml +0 -86
- package/benchmark-configs/lynkr.env +0 -48
- package/benchmark-configs/portkey-config.json +0 -60
- package/benchmark-configs/portkey-docker.sh +0 -23
- package/benchmark-tier-routing.js +0 -449
- package/funding.json +0 -110
- package/src/api/middleware/validation.js +0 -261
- package/src/routing/drift-monitor.js +0 -113
- package/src/workers/helpers.js +0 -185
package/src/memory/tools.js
CHANGED
|
@@ -13,19 +13,16 @@ const MAX_QUERY_LENGTH = 1000;
|
|
|
13
13
|
const MAX_CONTENT_LENGTH = 5000;
|
|
14
14
|
|
|
15
15
|
// ============================================================================
|
|
16
|
-
// MEMORY TOOLS
|
|
16
|
+
// MEMORY TOOLS
|
|
17
17
|
// ============================================================================
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Tool: memory_search
|
|
21
21
|
* Search long-term memories for relevant facts
|
|
22
|
-
*
|
|
23
|
-
* UPDATED: Added input validation to prevent FTS5 errors and injection
|
|
24
22
|
*/
|
|
25
23
|
async function memory_search(args, context = {}) {
|
|
26
24
|
const { query, limit = 10, type, category } = args;
|
|
27
25
|
|
|
28
|
-
// ✅ Validate query exists and is string
|
|
29
26
|
if (!query || typeof query !== 'string') {
|
|
30
27
|
return {
|
|
31
28
|
ok: false,
|
|
@@ -35,18 +32,16 @@ async function memory_search(args, context = {}) {
|
|
|
35
32
|
};
|
|
36
33
|
}
|
|
37
34
|
|
|
38
|
-
// ✅ Validate query length
|
|
39
35
|
if (query.length > MAX_QUERY_LENGTH) {
|
|
40
36
|
return {
|
|
41
37
|
ok: false,
|
|
42
|
-
content: JSON.stringify({
|
|
38
|
+
content: JSON.stringify({
|
|
43
39
|
error: `Query too long (max ${MAX_QUERY_LENGTH} characters)`,
|
|
44
40
|
provided: query.length
|
|
45
41
|
}),
|
|
46
42
|
};
|
|
47
43
|
}
|
|
48
44
|
|
|
49
|
-
// ✅ Validate type if provided
|
|
50
45
|
if (type && !VALID_TYPES.includes(type)) {
|
|
51
46
|
return {
|
|
52
47
|
ok: false,
|
|
@@ -57,7 +52,6 @@ async function memory_search(args, context = {}) {
|
|
|
57
52
|
};
|
|
58
53
|
}
|
|
59
54
|
|
|
60
|
-
// ✅ Validate category if provided
|
|
61
55
|
if (category && !VALID_CATEGORIES.includes(category)) {
|
|
62
56
|
return {
|
|
63
57
|
ok: false,
|
|
@@ -68,7 +62,6 @@ async function memory_search(args, context = {}) {
|
|
|
68
62
|
};
|
|
69
63
|
}
|
|
70
64
|
|
|
71
|
-
// ✅ Validate limit
|
|
72
65
|
if (typeof limit !== 'number' || limit < 1 || limit > 100) {
|
|
73
66
|
return {
|
|
74
67
|
ok: false,
|
|
@@ -121,8 +114,6 @@ async function memory_search(args, context = {}) {
|
|
|
121
114
|
/**
|
|
122
115
|
* Tool: memory_add
|
|
123
116
|
* Manually add a fact to long-term memory
|
|
124
|
-
*
|
|
125
|
-
* UPDATED: Enhanced validation
|
|
126
117
|
*/
|
|
127
118
|
async function memory_add(args, context = {}) {
|
|
128
119
|
const {
|
|
@@ -132,7 +123,6 @@ async function memory_add(args, context = {}) {
|
|
|
132
123
|
importance = 0.5,
|
|
133
124
|
} = args;
|
|
134
125
|
|
|
135
|
-
// ✅ Validate content
|
|
136
126
|
if (!content || typeof content !== 'string') {
|
|
137
127
|
return {
|
|
138
128
|
ok: false,
|
|
@@ -142,7 +132,6 @@ async function memory_add(args, context = {}) {
|
|
|
142
132
|
};
|
|
143
133
|
}
|
|
144
134
|
|
|
145
|
-
// ✅ Validate content length
|
|
146
135
|
if (content.length > MAX_CONTENT_LENGTH) {
|
|
147
136
|
return {
|
|
148
137
|
ok: false,
|
|
@@ -163,7 +152,6 @@ async function memory_add(args, context = {}) {
|
|
|
163
152
|
};
|
|
164
153
|
}
|
|
165
154
|
|
|
166
|
-
// ✅ Validate type
|
|
167
155
|
if (!VALID_TYPES.includes(type)) {
|
|
168
156
|
return {
|
|
169
157
|
ok: false,
|
|
@@ -174,7 +162,6 @@ async function memory_add(args, context = {}) {
|
|
|
174
162
|
};
|
|
175
163
|
}
|
|
176
164
|
|
|
177
|
-
// ✅ Validate category
|
|
178
165
|
if (!VALID_CATEGORIES.includes(category)) {
|
|
179
166
|
return {
|
|
180
167
|
ok: false,
|
|
@@ -185,7 +172,6 @@ async function memory_add(args, context = {}) {
|
|
|
185
172
|
};
|
|
186
173
|
}
|
|
187
174
|
|
|
188
|
-
// ✅ Validate importance
|
|
189
175
|
if (typeof importance !== 'number' || importance < 0 || importance > 1) {
|
|
190
176
|
return {
|
|
191
177
|
ok: false,
|
|
@@ -241,13 +227,10 @@ async function memory_add(args, context = {}) {
|
|
|
241
227
|
/**
|
|
242
228
|
* Tool: memory_forget
|
|
243
229
|
* Remove memories matching a query
|
|
244
|
-
*
|
|
245
|
-
* UPDATED: Enhanced validation
|
|
246
230
|
*/
|
|
247
231
|
async function memory_forget(args, context = {}) {
|
|
248
232
|
const { query, confirm = false } = args;
|
|
249
233
|
|
|
250
|
-
// ✅ Validate query
|
|
251
234
|
if (!query || typeof query !== 'string') {
|
|
252
235
|
return {
|
|
253
236
|
ok: false,
|
|
@@ -257,7 +240,6 @@ async function memory_forget(args, context = {}) {
|
|
|
257
240
|
};
|
|
258
241
|
}
|
|
259
242
|
|
|
260
|
-
// ✅ Validate query length
|
|
261
243
|
if (query.length > MAX_QUERY_LENGTH) {
|
|
262
244
|
return {
|
|
263
245
|
ok: false,
|
|
@@ -268,7 +250,6 @@ async function memory_forget(args, context = {}) {
|
|
|
268
250
|
};
|
|
269
251
|
}
|
|
270
252
|
|
|
271
|
-
// ✅ Validate confirm is boolean
|
|
272
253
|
if (typeof confirm !== 'boolean') {
|
|
273
254
|
return {
|
|
274
255
|
ok: false,
|
|
@@ -280,7 +261,6 @@ async function memory_forget(args, context = {}) {
|
|
|
280
261
|
}
|
|
281
262
|
|
|
282
263
|
try {
|
|
283
|
-
// Search for matching memories
|
|
284
264
|
const matches = search.searchMemories({
|
|
285
265
|
query,
|
|
286
266
|
limit: 50, // Check up to 50 matches
|
|
@@ -318,7 +298,6 @@ async function memory_forget(args, context = {}) {
|
|
|
318
298
|
};
|
|
319
299
|
}
|
|
320
300
|
|
|
321
|
-
// Delete all matching memories
|
|
322
301
|
let deletedCount = 0;
|
|
323
302
|
for (const memory of matches) {
|
|
324
303
|
const deleted = store.deleteMemory(memory.id);
|
|
@@ -386,7 +365,7 @@ async function memory_stats(args, context = {}) {
|
|
|
386
365
|
}
|
|
387
366
|
|
|
388
367
|
// ============================================================================
|
|
389
|
-
// TOOL DEFINITIONS
|
|
368
|
+
// TOOL DEFINITIONS
|
|
390
369
|
// ============================================================================
|
|
391
370
|
|
|
392
371
|
const MEMORY_TOOLS = {
|
|
@@ -90,10 +90,12 @@ function detectBypass({ payload, headers = {} }) {
|
|
|
90
90
|
};
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
// Pattern 3: Warmup / count probes —
|
|
93
|
+
// Pattern 3: Warmup / count / quota probes — single short user messages.
|
|
94
|
+
// Unbypassed probes reach a real model, whose confused replies get
|
|
95
|
+
// memory-extracted and re-injected into real turns.
|
|
94
96
|
if (messages.length === 1 && messages[0]?.role === "user") {
|
|
95
97
|
const firstText = getText(messages[0].content).trim();
|
|
96
|
-
if (firstText === "Warmup" || firstText === "count") {
|
|
98
|
+
if (firstText === "Warmup" || firstText === "count" || firstText === "quota") {
|
|
97
99
|
return { kind: firstText.toLowerCase(), text: "OK" };
|
|
98
100
|
}
|
|
99
101
|
}
|