@sentry/junior-memory 0.129.0 → 0.131.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/dist/index.js +1 -36
- package/dist/index.js.map +1 -1
- package/dist/ranking.d.ts +1 -5
- package/package.json +2 -2
- package/src/ranking.ts +1 -11
- package/src/store.ts +1 -45
package/dist/ranking.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { MemoryRecord } from "./store";
|
|
2
2
|
export interface MemoryMatch {
|
|
3
|
-
exactIdentifier: boolean;
|
|
4
3
|
lexical?: {
|
|
5
4
|
rank: number;
|
|
6
5
|
};
|
|
@@ -10,10 +9,7 @@ export interface MemoryMatch {
|
|
|
10
9
|
rank: number;
|
|
11
10
|
};
|
|
12
11
|
}
|
|
13
|
-
/**
|
|
14
|
-
* Keep exact structured-identifier matches in the strongest relevance tier,
|
|
15
|
-
* then fuse lexical and vector ranks without comparing provider raw scores.
|
|
16
|
-
*/
|
|
12
|
+
/** Fuse lexical and vector ranks without comparing provider raw scores. */
|
|
17
13
|
export declare function rankMemoryMatches(matches: MemoryMatch[], options: {
|
|
18
14
|
channelPrefix?: string;
|
|
19
15
|
nowMs: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-memory",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.131.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"commander": "^14.0.3",
|
|
28
28
|
"drizzle-orm": "^0.45.2",
|
|
29
29
|
"zod": "^4.4.3",
|
|
30
|
-
"@sentry/junior-plugin-api": "0.
|
|
30
|
+
"@sentry/junior-plugin-api": "0.131.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^25.9.1",
|
package/src/ranking.ts
CHANGED
|
@@ -4,7 +4,6 @@ const RECIPROCAL_RANK_FUSION_K = 60;
|
|
|
4
4
|
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
|
|
5
5
|
|
|
6
6
|
export interface MemoryMatch {
|
|
7
|
-
exactIdentifier: boolean;
|
|
8
7
|
lexical?: {
|
|
9
8
|
rank: number;
|
|
10
9
|
};
|
|
@@ -47,10 +46,7 @@ function observedAgeRank(memory: MemoryRecord, nowMs: number): number {
|
|
|
47
46
|
return 0;
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
/**
|
|
51
|
-
* Keep exact structured-identifier matches in the strongest relevance tier,
|
|
52
|
-
* then fuse lexical and vector ranks without comparing provider raw scores.
|
|
53
|
-
*/
|
|
49
|
+
/** Fuse lexical and vector ranks without comparing provider raw scores. */
|
|
54
50
|
export function rankMemoryMatches(
|
|
55
51
|
matches: MemoryMatch[],
|
|
56
52
|
options: {
|
|
@@ -67,17 +63,11 @@ export function rankMemoryMatches(
|
|
|
67
63
|
}
|
|
68
64
|
byId.set(match.memory.id, {
|
|
69
65
|
...existing,
|
|
70
|
-
exactIdentifier: existing.exactIdentifier || match.exactIdentifier,
|
|
71
66
|
...(match.lexical ? { lexical: match.lexical } : {}),
|
|
72
67
|
...(match.vector ? { vector: match.vector } : {}),
|
|
73
68
|
});
|
|
74
69
|
}
|
|
75
70
|
return [...byId.values()].sort((left, right) => {
|
|
76
|
-
const identifierDelta =
|
|
77
|
-
Number(right.exactIdentifier) - Number(left.exactIdentifier);
|
|
78
|
-
if (identifierDelta !== 0) {
|
|
79
|
-
return identifierDelta;
|
|
80
|
-
}
|
|
81
71
|
const scoreDelta = matchScore(right) - matchScore(left);
|
|
82
72
|
if (scoreDelta !== 0) {
|
|
83
73
|
return scoreDelta;
|
package/src/store.ts
CHANGED
|
@@ -591,22 +591,6 @@ export async function archiveExpiredMemoryBatch(args: {
|
|
|
591
591
|
return { archivedCount: archivedIds.length };
|
|
592
592
|
}
|
|
593
593
|
|
|
594
|
-
/**
|
|
595
|
-
* Find path-like, dotted, underscored, and multi-part hyphenated identifiers.
|
|
596
|
-
* Two-part hyphenated prose such as "long-running" remains ordinary text.
|
|
597
|
-
*/
|
|
598
|
-
function structuredQueryIdentifiers(query: string): string[] {
|
|
599
|
-
const matches =
|
|
600
|
-
query
|
|
601
|
-
.toLowerCase()
|
|
602
|
-
.match(
|
|
603
|
-
/(?:[a-z0-9][a-z0-9._-]*\/)+[a-z0-9][a-z0-9._-]*|[a-z0-9]+(?:[._][a-z0-9]+)+|[a-z0-9]+(?:-[a-z0-9]+){2,}/g,
|
|
604
|
-
) ?? [];
|
|
605
|
-
return [
|
|
606
|
-
...new Set(matches.map((identifier) => identifier.replace(/\.+$/, ""))),
|
|
607
|
-
];
|
|
608
|
-
}
|
|
609
|
-
|
|
610
594
|
function denseRanks<T>(
|
|
611
595
|
values: T[],
|
|
612
596
|
key: (value: T) => string | number,
|
|
@@ -984,48 +968,21 @@ async function searchVisibleLexicalMemories(args: {
|
|
|
984
968
|
)`;
|
|
985
969
|
const textsearch = sql`to_tsvector('english', ${juniorMemoryMemories.content})`;
|
|
986
970
|
const textRank = sql<number>`ts_rank_cd(${textsearch}, ${tsquery})`;
|
|
987
|
-
const identifiers = structuredQueryIdentifiers(args.query);
|
|
988
|
-
const contentTokens = sql`regexp_split_to_array(lower(${juniorMemoryMemories.content}), '[^a-z0-9._/-]+')`;
|
|
989
|
-
const identifierArray =
|
|
990
|
-
identifiers.length > 0
|
|
991
|
-
? sql`ARRAY[${sql.join(
|
|
992
|
-
identifiers.map((identifier) => sql`${identifier}`),
|
|
993
|
-
sql`, `,
|
|
994
|
-
)}]::text[]`
|
|
995
|
-
: undefined;
|
|
996
|
-
const exactIdentifierMatch =
|
|
997
|
-
identifierArray !== undefined
|
|
998
|
-
? sql<boolean>`EXISTS (
|
|
999
|
-
SELECT 1
|
|
1000
|
-
FROM unnest(${contentTokens}) AS content_token(value)
|
|
1001
|
-
CROSS JOIN unnest(${identifierArray}) AS query_identifier(value)
|
|
1002
|
-
WHERE strpos(
|
|
1003
|
-
'/' || regexp_replace(content_token.value, '\\.+$', '') || '/',
|
|
1004
|
-
'/' || query_identifier.value || '/'
|
|
1005
|
-
) > 0
|
|
1006
|
-
)`
|
|
1007
|
-
: sql<boolean>`false`;
|
|
1008
971
|
const rows = await args.db
|
|
1009
972
|
.select({
|
|
1010
|
-
exactIdentifierMatch,
|
|
1011
973
|
memory: juniorMemoryMemories,
|
|
1012
974
|
textRank,
|
|
1013
975
|
})
|
|
1014
976
|
.from(juniorMemoryMemories)
|
|
1015
977
|
.where(and(predicate, sql`${textsearch} @@ ${tsquery}`))
|
|
1016
978
|
.orderBy(
|
|
1017
|
-
...(identifiers.length > 0 ? [desc(exactIdentifierMatch)] : []),
|
|
1018
979
|
desc(textRank),
|
|
1019
980
|
desc(juniorMemoryMemories.observedAtMs),
|
|
1020
981
|
asc(juniorMemoryMemories.id),
|
|
1021
982
|
)
|
|
1022
983
|
.limit(args.limit);
|
|
1023
|
-
const ranks = denseRanks(
|
|
1024
|
-
rows,
|
|
1025
|
-
(row) => `${row.exactIdentifierMatch}:${Number(row.textRank)}`,
|
|
1026
|
-
);
|
|
984
|
+
const ranks = denseRanks(rows, (row) => Number(row.textRank));
|
|
1027
985
|
return rows.map((row, index) => ({
|
|
1028
|
-
exactIdentifier: row.exactIdentifierMatch,
|
|
1029
986
|
lexical: { rank: ranks[index] },
|
|
1030
987
|
memory: parseMemoryRow(row.memory),
|
|
1031
988
|
sourceKey: row.memory.sourceKey,
|
|
@@ -1100,7 +1057,6 @@ async function searchVisibleVectorMemories(args: {
|
|
|
1100
1057
|
}
|
|
1101
1058
|
return [
|
|
1102
1059
|
{
|
|
1103
|
-
exactIdentifier: false,
|
|
1104
1060
|
memory: parseMemoryRow(row.memory),
|
|
1105
1061
|
sourceKey: row.memory.sourceKey,
|
|
1106
1062
|
vector: {
|