@anuma/sdk 6.29.2 → 6.30.1
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/expo/index.cjs +89 -32
- package/dist/expo/index.d.mts +4 -0
- package/dist/expo/index.d.ts +4 -0
- package/dist/expo/index.mjs +89 -32
- package/dist/memory/context.cjs +8 -2
- package/dist/memory/context.d.mts +3 -0
- package/dist/memory/context.d.ts +3 -0
- package/dist/memory/context.mjs +8 -2
- package/dist/react/index.cjs +91 -33
- package/dist/react/index.d.mts +4 -0
- package/dist/react/index.d.ts +4 -0
- package/dist/react/index.mjs +91 -33
- package/dist/server/index.cjs +116 -32
- package/dist/server/index.d.mts +3 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.mjs +116 -32
- package/dist/tools/index.cjs +2 -1
- package/dist/tools/index.mjs +2 -1
- package/package.json +1 -1
package/dist/expo/index.cjs
CHANGED
|
@@ -18674,6 +18674,11 @@ function formatEventTime(start, end, kind) {
|
|
|
18674
18674
|
if (kind === "ongoing") return `, event: since ${startDate}`;
|
|
18675
18675
|
return `, event: ${startDate}`;
|
|
18676
18676
|
}
|
|
18677
|
+
function formatSavedTime(createdAt) {
|
|
18678
|
+
const ms = createdAt?.getTime();
|
|
18679
|
+
if (ms === void 0 || !Number.isFinite(ms) || ms <= 0) return "";
|
|
18680
|
+
return `, saved: ${new Date(ms).toISOString().slice(0, 10)}`;
|
|
18681
|
+
}
|
|
18677
18682
|
function generateFenceNonce() {
|
|
18678
18683
|
const bytes = new Uint8Array(9);
|
|
18679
18684
|
crypto.getRandomValues(bytes);
|
|
@@ -18692,8 +18697,9 @@ function formatRecallResult(memories) {
|
|
|
18692
18697
|
const lines = memories.map((m, i) => {
|
|
18693
18698
|
let body;
|
|
18694
18699
|
if (m.kind === "fact") {
|
|
18700
|
+
const savedSuffix = formatSavedTime(m.createdAt);
|
|
18695
18701
|
const eventSuffix = formatEventTime(m.eventTimeStart, m.eventTimeEnd, m.eventTimeKind);
|
|
18696
|
-
body = `[${i + 1}] fact (id: ${m.id}${eventSuffix})
|
|
18702
|
+
body = `[${i + 1}] fact (id: ${m.id}${savedSuffix}${eventSuffix})
|
|
18697
18703
|
${m.content}`;
|
|
18698
18704
|
} else {
|
|
18699
18705
|
const date10 = m.createdAt.toISOString().slice(0, 10);
|
|
@@ -18743,6 +18749,40 @@ function isDumpQuery(query) {
|
|
|
18743
18749
|
if (EVERYTHING_YOU_KNOW_RE.test(q)) return true;
|
|
18744
18750
|
return false;
|
|
18745
18751
|
}
|
|
18752
|
+
async function listRecentFacts(ctx, limit, toolOptions) {
|
|
18753
|
+
const vaultCtx = ctx.vaultCtx;
|
|
18754
|
+
if (!vaultCtx) return [];
|
|
18755
|
+
const ordered = await getVaultRankingProjectionsOp(vaultCtx, {
|
|
18756
|
+
...toolOptions?.scopes && { scopes: toolOptions.scopes },
|
|
18757
|
+
...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds },
|
|
18758
|
+
...toolOptions?.folderId !== void 0 && { folderId: toolOptions.folderId }
|
|
18759
|
+
});
|
|
18760
|
+
const readable = [];
|
|
18761
|
+
for (let i = 0; i < ordered.length && readable.length < limit; i += limit) {
|
|
18762
|
+
const batch = ordered.slice(i, i + limit).map((p) => p.uniqueId);
|
|
18763
|
+
const byId = new Map(
|
|
18764
|
+
(await getVaultMemoriesByIdsOp(vaultCtx, batch)).map((m) => [m.uniqueId, m])
|
|
18765
|
+
);
|
|
18766
|
+
for (const id of batch) {
|
|
18767
|
+
const m = byId.get(id);
|
|
18768
|
+
if (m && !isEncrypted(m.content)) readable.push(m);
|
|
18769
|
+
if (readable.length >= limit) break;
|
|
18770
|
+
}
|
|
18771
|
+
}
|
|
18772
|
+
return readable.map((m) => ({
|
|
18773
|
+
id: m.uniqueId,
|
|
18774
|
+
kind: "fact",
|
|
18775
|
+
content: m.content,
|
|
18776
|
+
score: 0,
|
|
18777
|
+
folderId: m.folderId,
|
|
18778
|
+
eventTimeStart: m.eventTimeStart,
|
|
18779
|
+
eventTimeEnd: m.eventTimeEnd,
|
|
18780
|
+
eventTimeKind: m.eventTimeKind,
|
|
18781
|
+
factType: m.factType,
|
|
18782
|
+
createdAt: m.createdAt,
|
|
18783
|
+
updatedAt: m.updatedAt
|
|
18784
|
+
}));
|
|
18785
|
+
}
|
|
18746
18786
|
function createRecallTool(ctx, toolOptions, callbacks) {
|
|
18747
18787
|
const defaultTypes = toolOptions?.types ?? ["fact", "chunk"];
|
|
18748
18788
|
const defaultLimit = toolOptions?.limit ?? DEFAULT_LIMIT2;
|
|
@@ -18755,7 +18795,7 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
18755
18795
|
type: "function",
|
|
18756
18796
|
function: {
|
|
18757
18797
|
name: RECALL_TOOL_NAME,
|
|
18758
|
-
description:
|
|
18798
|
+
description: 'Search the user\'s memory across stored facts/preferences and past conversation excerpts. Returns a unified ranked list \u2014 facts carry an `id` you can reference and the date they were saved; conversation excerpts carry a date and role. Use this whenever the user\'s question may relate to anything previously discussed or saved (preferences, prior decisions, past topics). Phrase the query naturally. For multi-faceted / overview questions ("tell me about the user", "what\'s my tech stack"), prefer several targeted searches \u2014 one facet each (e.g. name, work, hobbies) \u2014 over a single broad query; fuse the results yourself. For "what did I save recently / latest memories" questions, set `sort` to "recent" to get the newest saved facts, newest first, instead of a relevance search.',
|
|
18759
18799
|
arguments: {
|
|
18760
18800
|
type: "object",
|
|
18761
18801
|
properties: {
|
|
@@ -18766,6 +18806,11 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
18766
18806
|
limit: {
|
|
18767
18807
|
type: "integer",
|
|
18768
18808
|
description: `Max number of results. Default: ${defaultLimit}.`
|
|
18809
|
+
},
|
|
18810
|
+
sort: {
|
|
18811
|
+
type: "string",
|
|
18812
|
+
enum: ["relevance", "recent"],
|
|
18813
|
+
description: `"relevance" (default) ranks by match to the query. "recent" returns the newest saved facts, newest first, and ignores the query's topic.`
|
|
18769
18814
|
}
|
|
18770
18815
|
},
|
|
18771
18816
|
required: ["query"]
|
|
@@ -18810,35 +18855,41 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
18810
18855
|
let surfaced = 0;
|
|
18811
18856
|
try {
|
|
18812
18857
|
let recallDegraded = [];
|
|
18813
|
-
|
|
18814
|
-
|
|
18815
|
-
|
|
18816
|
-
|
|
18817
|
-
|
|
18858
|
+
const wantsRecent = args.sort === "recent" && defaultTypes.includes("fact") && ctx.vaultCtx !== void 0;
|
|
18859
|
+
let result;
|
|
18860
|
+
if (wantsRecent) {
|
|
18861
|
+
result = { memories: await listRecentFacts(ctx, effectiveLimit, toolOptions) };
|
|
18862
|
+
} else {
|
|
18863
|
+
let subQueries;
|
|
18864
|
+
if (defaultBudget === "high" && toolOptions?.decomposeOptions) {
|
|
18865
|
+
const decomp = await decomposeQuery(query, toolOptions.decomposeOptions);
|
|
18866
|
+
if (decomp.mode === "composite" && decomp.subQueries.length >= 2) {
|
|
18867
|
+
subQueries = decomp.subQueries;
|
|
18868
|
+
}
|
|
18818
18869
|
}
|
|
18870
|
+
const recallOpts = {
|
|
18871
|
+
onDiagnostics: (d) => {
|
|
18872
|
+
recallDegraded = d.degraded;
|
|
18873
|
+
},
|
|
18874
|
+
types: defaultTypes,
|
|
18875
|
+
limit: effectiveLimit,
|
|
18876
|
+
budget: defaultBudget,
|
|
18877
|
+
...toolOptions?.minScore !== void 0 && { minScore: toolOptions.minScore },
|
|
18878
|
+
...toolOptions?.scopes && { scopes: toolOptions.scopes },
|
|
18879
|
+
...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds },
|
|
18880
|
+
...toolOptions?.folderId !== void 0 && { folderId: toolOptions.folderId },
|
|
18881
|
+
...toolOptions?.excludeConversationId && {
|
|
18882
|
+
excludeConversationId: toolOptions.excludeConversationId
|
|
18883
|
+
},
|
|
18884
|
+
// Do NOT forward decomposeOptions into recall() — rewrite already
|
|
18885
|
+
// ran above, and forwarding would falsely trip `decompose-moved`
|
|
18886
|
+
// on every specific-mode high-budget call. graphRefine auth can
|
|
18887
|
+
// be threaded later when the tool opts into that path.
|
|
18888
|
+
...toolOptions?.now !== void 0 && { now: toolOptions.now },
|
|
18889
|
+
...subQueries && { subQueries }
|
|
18890
|
+
};
|
|
18891
|
+
result = await recall(query, ctx, recallOpts);
|
|
18819
18892
|
}
|
|
18820
|
-
const recallOpts = {
|
|
18821
|
-
onDiagnostics: (d) => {
|
|
18822
|
-
recallDegraded = d.degraded;
|
|
18823
|
-
},
|
|
18824
|
-
types: defaultTypes,
|
|
18825
|
-
limit: effectiveLimit,
|
|
18826
|
-
budget: defaultBudget,
|
|
18827
|
-
...toolOptions?.minScore !== void 0 && { minScore: toolOptions.minScore },
|
|
18828
|
-
...toolOptions?.scopes && { scopes: toolOptions.scopes },
|
|
18829
|
-
...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds },
|
|
18830
|
-
...toolOptions?.folderId !== void 0 && { folderId: toolOptions.folderId },
|
|
18831
|
-
...toolOptions?.excludeConversationId && {
|
|
18832
|
-
excludeConversationId: toolOptions.excludeConversationId
|
|
18833
|
-
},
|
|
18834
|
-
// Do NOT forward decomposeOptions into recall() — rewrite already
|
|
18835
|
-
// ran above, and forwarding would falsely trip `decompose-moved`
|
|
18836
|
-
// on every specific-mode high-budget call. graphRefine auth can
|
|
18837
|
-
// be threaded later when the tool opts into that path.
|
|
18838
|
-
...toolOptions?.now !== void 0 && { now: toolOptions.now },
|
|
18839
|
-
...subQueries && { subQueries }
|
|
18840
|
-
};
|
|
18841
|
-
const result = await recall(query, ctx, recallOpts);
|
|
18842
18893
|
if (callbacks?.onChunksRetrieved) {
|
|
18843
18894
|
const convIds = Array.from(
|
|
18844
18895
|
new Set(
|
|
@@ -18851,7 +18902,7 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
18851
18902
|
const facts = result.memories.filter((m) => m.kind === "fact").map((m) => ({ id: m.id, score: m.score }));
|
|
18852
18903
|
if (facts.length > 0) {
|
|
18853
18904
|
callbacks.onFactsRetrieved?.(facts.map((f) => f.id));
|
|
18854
|
-
callbacks.onFactsRanked?.(facts);
|
|
18905
|
+
if (!wantsRecent) callbacks.onFactsRanked?.(facts);
|
|
18855
18906
|
}
|
|
18856
18907
|
}
|
|
18857
18908
|
surfaced = result.memories.length;
|
|
@@ -20032,6 +20083,10 @@ function createMessageSourceResolver(ctx) {
|
|
|
20032
20083
|
}
|
|
20033
20084
|
|
|
20034
20085
|
// src/lib/memory/context.ts
|
|
20086
|
+
function savedAt(createdAt) {
|
|
20087
|
+
const ms = createdAt?.getTime();
|
|
20088
|
+
return ms !== void 0 && Number.isFinite(ms) && ms > 0 ? { createdAt } : {};
|
|
20089
|
+
}
|
|
20035
20090
|
function shouldRecallMemory(query) {
|
|
20036
20091
|
const normalized = query.trim().toLowerCase().replace(/[.!?。!?¡¿]+$/u, "").replace(/^[¡¿]+/u, "");
|
|
20037
20092
|
return normalized.length > 0 && !/^(hi|hi there|hello|hey|yes|no|yep|nope|sure|k|ok|okay|thanks|thank you|thank you very much|thanks a lot|cool|great|got it|sounds good|hola|buenos días|buenas|sí|si|gracias|muchas gracias|vale|bonjour|salut|oui|non|merci|merci beaucoup|d'accord|hallo|guten tag|ja|nein|danke|danke schön|alles klar|olá|obrigado|obrigada|ciao|grazie|sì|你好|谢谢|好的|こんにちは|ありがとう|안녕하세요|감사합니다)$/u.test(
|
|
@@ -20069,7 +20124,8 @@ async function assembleMemoryContext(options) {
|
|
|
20069
20124
|
content: m.content,
|
|
20070
20125
|
score,
|
|
20071
20126
|
lane,
|
|
20072
|
-
sourceIds: m.sourceChunkIds ?? []
|
|
20127
|
+
sourceIds: m.sourceChunkIds ?? [],
|
|
20128
|
+
...savedAt(m.createdAt)
|
|
20073
20129
|
});
|
|
20074
20130
|
const empty = {
|
|
20075
20131
|
memories: [],
|
|
@@ -20134,7 +20190,8 @@ async function assembleMemoryContext(options) {
|
|
|
20134
20190
|
score: m.score,
|
|
20135
20191
|
lane,
|
|
20136
20192
|
...lane === "fact" && { recalled: true },
|
|
20137
|
-
sourceIds: m.sourceChunkIds ?? (m.messageId ? [m.messageId] : [])
|
|
20193
|
+
sourceIds: m.sourceChunkIds ?? (m.messageId ? [m.messageId] : []),
|
|
20194
|
+
...savedAt(m.createdAt)
|
|
20138
20195
|
}));
|
|
20139
20196
|
const recalledFacts = toItems(facts, "fact");
|
|
20140
20197
|
const recalledScores = /* @__PURE__ */ new Map();
|
package/dist/expo/index.d.mts
CHANGED
|
@@ -7106,6 +7106,7 @@ declare function getVaultRankingProjectionsOp(ctx: VaultMemoryOperationsContext,
|
|
|
7106
7106
|
since?: Date;
|
|
7107
7107
|
limit?: number;
|
|
7108
7108
|
folderId?: string | null;
|
|
7109
|
+
memoryIds?: string[];
|
|
7109
7110
|
}): Promise<RankableVaultMemory[]>;
|
|
7110
7111
|
/**
|
|
7111
7112
|
* Bulk-decrypt a KNOWN set of memories by ID — the "decrypt last" half of
|
|
@@ -9552,6 +9553,9 @@ interface MemoryContextItem {
|
|
|
9552
9553
|
sourceIds: string[];
|
|
9553
9554
|
/** Ranked fact evidence, retained when profile deduplication wins placement. */
|
|
9554
9555
|
recalled?: boolean;
|
|
9556
|
+
/** When the memory was written — lets the prompt show a saved date so the
|
|
9557
|
+
* model can answer "what did I save recently". */
|
|
9558
|
+
createdAt?: Date;
|
|
9555
9559
|
}
|
|
9556
9560
|
interface MemoryContextOptions {
|
|
9557
9561
|
query: string;
|
package/dist/expo/index.d.ts
CHANGED
|
@@ -7106,6 +7106,7 @@ declare function getVaultRankingProjectionsOp(ctx: VaultMemoryOperationsContext,
|
|
|
7106
7106
|
since?: Date;
|
|
7107
7107
|
limit?: number;
|
|
7108
7108
|
folderId?: string | null;
|
|
7109
|
+
memoryIds?: string[];
|
|
7109
7110
|
}): Promise<RankableVaultMemory[]>;
|
|
7110
7111
|
/**
|
|
7111
7112
|
* Bulk-decrypt a KNOWN set of memories by ID — the "decrypt last" half of
|
|
@@ -9552,6 +9553,9 @@ interface MemoryContextItem {
|
|
|
9552
9553
|
sourceIds: string[];
|
|
9553
9554
|
/** Ranked fact evidence, retained when profile deduplication wins placement. */
|
|
9554
9555
|
recalled?: boolean;
|
|
9556
|
+
/** When the memory was written — lets the prompt show a saved date so the
|
|
9557
|
+
* model can answer "what did I save recently". */
|
|
9558
|
+
createdAt?: Date;
|
|
9555
9559
|
}
|
|
9556
9560
|
interface MemoryContextOptions {
|
|
9557
9561
|
query: string;
|
package/dist/expo/index.mjs
CHANGED
|
@@ -17016,6 +17016,11 @@ function formatEventTime(start, end, kind) {
|
|
|
17016
17016
|
if (kind === "ongoing") return `, event: since ${startDate}`;
|
|
17017
17017
|
return `, event: ${startDate}`;
|
|
17018
17018
|
}
|
|
17019
|
+
function formatSavedTime(createdAt) {
|
|
17020
|
+
const ms = createdAt?.getTime();
|
|
17021
|
+
if (ms === void 0 || !Number.isFinite(ms) || ms <= 0) return "";
|
|
17022
|
+
return `, saved: ${new Date(ms).toISOString().slice(0, 10)}`;
|
|
17023
|
+
}
|
|
17019
17024
|
function generateFenceNonce() {
|
|
17020
17025
|
const bytes = new Uint8Array(9);
|
|
17021
17026
|
crypto.getRandomValues(bytes);
|
|
@@ -17034,8 +17039,9 @@ function formatRecallResult(memories) {
|
|
|
17034
17039
|
const lines = memories.map((m, i) => {
|
|
17035
17040
|
let body;
|
|
17036
17041
|
if (m.kind === "fact") {
|
|
17042
|
+
const savedSuffix = formatSavedTime(m.createdAt);
|
|
17037
17043
|
const eventSuffix = formatEventTime(m.eventTimeStart, m.eventTimeEnd, m.eventTimeKind);
|
|
17038
|
-
body = `[${i + 1}] fact (id: ${m.id}${eventSuffix})
|
|
17044
|
+
body = `[${i + 1}] fact (id: ${m.id}${savedSuffix}${eventSuffix})
|
|
17039
17045
|
${m.content}`;
|
|
17040
17046
|
} else {
|
|
17041
17047
|
const date10 = m.createdAt.toISOString().slice(0, 10);
|
|
@@ -17085,6 +17091,40 @@ function isDumpQuery(query) {
|
|
|
17085
17091
|
if (EVERYTHING_YOU_KNOW_RE.test(q)) return true;
|
|
17086
17092
|
return false;
|
|
17087
17093
|
}
|
|
17094
|
+
async function listRecentFacts(ctx, limit, toolOptions) {
|
|
17095
|
+
const vaultCtx = ctx.vaultCtx;
|
|
17096
|
+
if (!vaultCtx) return [];
|
|
17097
|
+
const ordered = await getVaultRankingProjectionsOp(vaultCtx, {
|
|
17098
|
+
...toolOptions?.scopes && { scopes: toolOptions.scopes },
|
|
17099
|
+
...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds },
|
|
17100
|
+
...toolOptions?.folderId !== void 0 && { folderId: toolOptions.folderId }
|
|
17101
|
+
});
|
|
17102
|
+
const readable = [];
|
|
17103
|
+
for (let i = 0; i < ordered.length && readable.length < limit; i += limit) {
|
|
17104
|
+
const batch = ordered.slice(i, i + limit).map((p) => p.uniqueId);
|
|
17105
|
+
const byId = new Map(
|
|
17106
|
+
(await getVaultMemoriesByIdsOp(vaultCtx, batch)).map((m) => [m.uniqueId, m])
|
|
17107
|
+
);
|
|
17108
|
+
for (const id of batch) {
|
|
17109
|
+
const m = byId.get(id);
|
|
17110
|
+
if (m && !isEncrypted(m.content)) readable.push(m);
|
|
17111
|
+
if (readable.length >= limit) break;
|
|
17112
|
+
}
|
|
17113
|
+
}
|
|
17114
|
+
return readable.map((m) => ({
|
|
17115
|
+
id: m.uniqueId,
|
|
17116
|
+
kind: "fact",
|
|
17117
|
+
content: m.content,
|
|
17118
|
+
score: 0,
|
|
17119
|
+
folderId: m.folderId,
|
|
17120
|
+
eventTimeStart: m.eventTimeStart,
|
|
17121
|
+
eventTimeEnd: m.eventTimeEnd,
|
|
17122
|
+
eventTimeKind: m.eventTimeKind,
|
|
17123
|
+
factType: m.factType,
|
|
17124
|
+
createdAt: m.createdAt,
|
|
17125
|
+
updatedAt: m.updatedAt
|
|
17126
|
+
}));
|
|
17127
|
+
}
|
|
17088
17128
|
function createRecallTool(ctx, toolOptions, callbacks) {
|
|
17089
17129
|
const defaultTypes = toolOptions?.types ?? ["fact", "chunk"];
|
|
17090
17130
|
const defaultLimit = toolOptions?.limit ?? DEFAULT_LIMIT2;
|
|
@@ -17097,7 +17137,7 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
17097
17137
|
type: "function",
|
|
17098
17138
|
function: {
|
|
17099
17139
|
name: RECALL_TOOL_NAME,
|
|
17100
|
-
description:
|
|
17140
|
+
description: 'Search the user\'s memory across stored facts/preferences and past conversation excerpts. Returns a unified ranked list \u2014 facts carry an `id` you can reference and the date they were saved; conversation excerpts carry a date and role. Use this whenever the user\'s question may relate to anything previously discussed or saved (preferences, prior decisions, past topics). Phrase the query naturally. For multi-faceted / overview questions ("tell me about the user", "what\'s my tech stack"), prefer several targeted searches \u2014 one facet each (e.g. name, work, hobbies) \u2014 over a single broad query; fuse the results yourself. For "what did I save recently / latest memories" questions, set `sort` to "recent" to get the newest saved facts, newest first, instead of a relevance search.',
|
|
17101
17141
|
arguments: {
|
|
17102
17142
|
type: "object",
|
|
17103
17143
|
properties: {
|
|
@@ -17108,6 +17148,11 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
17108
17148
|
limit: {
|
|
17109
17149
|
type: "integer",
|
|
17110
17150
|
description: `Max number of results. Default: ${defaultLimit}.`
|
|
17151
|
+
},
|
|
17152
|
+
sort: {
|
|
17153
|
+
type: "string",
|
|
17154
|
+
enum: ["relevance", "recent"],
|
|
17155
|
+
description: `"relevance" (default) ranks by match to the query. "recent" returns the newest saved facts, newest first, and ignores the query's topic.`
|
|
17111
17156
|
}
|
|
17112
17157
|
},
|
|
17113
17158
|
required: ["query"]
|
|
@@ -17152,35 +17197,41 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
17152
17197
|
let surfaced = 0;
|
|
17153
17198
|
try {
|
|
17154
17199
|
let recallDegraded = [];
|
|
17155
|
-
|
|
17156
|
-
|
|
17157
|
-
|
|
17158
|
-
|
|
17159
|
-
|
|
17200
|
+
const wantsRecent = args.sort === "recent" && defaultTypes.includes("fact") && ctx.vaultCtx !== void 0;
|
|
17201
|
+
let result;
|
|
17202
|
+
if (wantsRecent) {
|
|
17203
|
+
result = { memories: await listRecentFacts(ctx, effectiveLimit, toolOptions) };
|
|
17204
|
+
} else {
|
|
17205
|
+
let subQueries;
|
|
17206
|
+
if (defaultBudget === "high" && toolOptions?.decomposeOptions) {
|
|
17207
|
+
const decomp = await decomposeQuery(query, toolOptions.decomposeOptions);
|
|
17208
|
+
if (decomp.mode === "composite" && decomp.subQueries.length >= 2) {
|
|
17209
|
+
subQueries = decomp.subQueries;
|
|
17210
|
+
}
|
|
17160
17211
|
}
|
|
17212
|
+
const recallOpts = {
|
|
17213
|
+
onDiagnostics: (d) => {
|
|
17214
|
+
recallDegraded = d.degraded;
|
|
17215
|
+
},
|
|
17216
|
+
types: defaultTypes,
|
|
17217
|
+
limit: effectiveLimit,
|
|
17218
|
+
budget: defaultBudget,
|
|
17219
|
+
...toolOptions?.minScore !== void 0 && { minScore: toolOptions.minScore },
|
|
17220
|
+
...toolOptions?.scopes && { scopes: toolOptions.scopes },
|
|
17221
|
+
...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds },
|
|
17222
|
+
...toolOptions?.folderId !== void 0 && { folderId: toolOptions.folderId },
|
|
17223
|
+
...toolOptions?.excludeConversationId && {
|
|
17224
|
+
excludeConversationId: toolOptions.excludeConversationId
|
|
17225
|
+
},
|
|
17226
|
+
// Do NOT forward decomposeOptions into recall() — rewrite already
|
|
17227
|
+
// ran above, and forwarding would falsely trip `decompose-moved`
|
|
17228
|
+
// on every specific-mode high-budget call. graphRefine auth can
|
|
17229
|
+
// be threaded later when the tool opts into that path.
|
|
17230
|
+
...toolOptions?.now !== void 0 && { now: toolOptions.now },
|
|
17231
|
+
...subQueries && { subQueries }
|
|
17232
|
+
};
|
|
17233
|
+
result = await recall(query, ctx, recallOpts);
|
|
17161
17234
|
}
|
|
17162
|
-
const recallOpts = {
|
|
17163
|
-
onDiagnostics: (d) => {
|
|
17164
|
-
recallDegraded = d.degraded;
|
|
17165
|
-
},
|
|
17166
|
-
types: defaultTypes,
|
|
17167
|
-
limit: effectiveLimit,
|
|
17168
|
-
budget: defaultBudget,
|
|
17169
|
-
...toolOptions?.minScore !== void 0 && { minScore: toolOptions.minScore },
|
|
17170
|
-
...toolOptions?.scopes && { scopes: toolOptions.scopes },
|
|
17171
|
-
...toolOptions?.memoryIds !== void 0 && { memoryIds: toolOptions.memoryIds },
|
|
17172
|
-
...toolOptions?.folderId !== void 0 && { folderId: toolOptions.folderId },
|
|
17173
|
-
...toolOptions?.excludeConversationId && {
|
|
17174
|
-
excludeConversationId: toolOptions.excludeConversationId
|
|
17175
|
-
},
|
|
17176
|
-
// Do NOT forward decomposeOptions into recall() — rewrite already
|
|
17177
|
-
// ran above, and forwarding would falsely trip `decompose-moved`
|
|
17178
|
-
// on every specific-mode high-budget call. graphRefine auth can
|
|
17179
|
-
// be threaded later when the tool opts into that path.
|
|
17180
|
-
...toolOptions?.now !== void 0 && { now: toolOptions.now },
|
|
17181
|
-
...subQueries && { subQueries }
|
|
17182
|
-
};
|
|
17183
|
-
const result = await recall(query, ctx, recallOpts);
|
|
17184
17235
|
if (callbacks?.onChunksRetrieved) {
|
|
17185
17236
|
const convIds = Array.from(
|
|
17186
17237
|
new Set(
|
|
@@ -17193,7 +17244,7 @@ function createRecallTool(ctx, toolOptions, callbacks) {
|
|
|
17193
17244
|
const facts = result.memories.filter((m) => m.kind === "fact").map((m) => ({ id: m.id, score: m.score }));
|
|
17194
17245
|
if (facts.length > 0) {
|
|
17195
17246
|
callbacks.onFactsRetrieved?.(facts.map((f) => f.id));
|
|
17196
|
-
callbacks.onFactsRanked?.(facts);
|
|
17247
|
+
if (!wantsRecent) callbacks.onFactsRanked?.(facts);
|
|
17197
17248
|
}
|
|
17198
17249
|
}
|
|
17199
17250
|
surfaced = result.memories.length;
|
|
@@ -18362,6 +18413,10 @@ function createMessageSourceResolver(ctx) {
|
|
|
18362
18413
|
}
|
|
18363
18414
|
|
|
18364
18415
|
// src/lib/memory/context.ts
|
|
18416
|
+
function savedAt(createdAt) {
|
|
18417
|
+
const ms = createdAt?.getTime();
|
|
18418
|
+
return ms !== void 0 && Number.isFinite(ms) && ms > 0 ? { createdAt } : {};
|
|
18419
|
+
}
|
|
18365
18420
|
function shouldRecallMemory(query) {
|
|
18366
18421
|
const normalized = query.trim().toLowerCase().replace(/[.!?。!?¡¿]+$/u, "").replace(/^[¡¿]+/u, "");
|
|
18367
18422
|
return normalized.length > 0 && !/^(hi|hi there|hello|hey|yes|no|yep|nope|sure|k|ok|okay|thanks|thank you|thank you very much|thanks a lot|cool|great|got it|sounds good|hola|buenos días|buenas|sí|si|gracias|muchas gracias|vale|bonjour|salut|oui|non|merci|merci beaucoup|d'accord|hallo|guten tag|ja|nein|danke|danke schön|alles klar|olá|obrigado|obrigada|ciao|grazie|sì|你好|谢谢|好的|こんにちは|ありがとう|안녕하세요|감사합니다)$/u.test(
|
|
@@ -18399,7 +18454,8 @@ async function assembleMemoryContext(options) {
|
|
|
18399
18454
|
content: m.content,
|
|
18400
18455
|
score,
|
|
18401
18456
|
lane,
|
|
18402
|
-
sourceIds: m.sourceChunkIds ?? []
|
|
18457
|
+
sourceIds: m.sourceChunkIds ?? [],
|
|
18458
|
+
...savedAt(m.createdAt)
|
|
18403
18459
|
});
|
|
18404
18460
|
const empty = {
|
|
18405
18461
|
memories: [],
|
|
@@ -18464,7 +18520,8 @@ async function assembleMemoryContext(options) {
|
|
|
18464
18520
|
score: m.score,
|
|
18465
18521
|
lane,
|
|
18466
18522
|
...lane === "fact" && { recalled: true },
|
|
18467
|
-
sourceIds: m.sourceChunkIds ?? (m.messageId ? [m.messageId] : [])
|
|
18523
|
+
sourceIds: m.sourceChunkIds ?? (m.messageId ? [m.messageId] : []),
|
|
18524
|
+
...savedAt(m.createdAt)
|
|
18468
18525
|
}));
|
|
18469
18526
|
const recalledFacts = toItems(facts, "fact");
|
|
18470
18527
|
const recalledScores = /* @__PURE__ */ new Map();
|
package/dist/memory/context.cjs
CHANGED
|
@@ -24,6 +24,10 @@ __export(context_exports, {
|
|
|
24
24
|
shouldRecallMemory: () => shouldRecallMemory
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(context_exports);
|
|
27
|
+
function savedAt(createdAt) {
|
|
28
|
+
const ms = createdAt?.getTime();
|
|
29
|
+
return ms !== void 0 && Number.isFinite(ms) && ms > 0 ? { createdAt } : {};
|
|
30
|
+
}
|
|
27
31
|
function shouldRecallMemory(query) {
|
|
28
32
|
const normalized = query.trim().toLowerCase().replace(/[.!?。!?¡¿]+$/u, "").replace(/^[¡¿]+/u, "");
|
|
29
33
|
return normalized.length > 0 && !/^(hi|hi there|hello|hey|yes|no|yep|nope|sure|k|ok|okay|thanks|thank you|thank you very much|thanks a lot|cool|great|got it|sounds good|hola|buenos días|buenas|sí|si|gracias|muchas gracias|vale|bonjour|salut|oui|non|merci|merci beaucoup|d'accord|hallo|guten tag|ja|nein|danke|danke schön|alles klar|olá|obrigado|obrigada|ciao|grazie|sì|你好|谢谢|好的|こんにちは|ありがとう|안녕하세요|감사합니다)$/u.test(
|
|
@@ -61,7 +65,8 @@ async function assembleMemoryContext(options) {
|
|
|
61
65
|
content: m.content,
|
|
62
66
|
score,
|
|
63
67
|
lane,
|
|
64
|
-
sourceIds: m.sourceChunkIds ?? []
|
|
68
|
+
sourceIds: m.sourceChunkIds ?? [],
|
|
69
|
+
...savedAt(m.createdAt)
|
|
65
70
|
});
|
|
66
71
|
const empty = {
|
|
67
72
|
memories: [],
|
|
@@ -126,7 +131,8 @@ async function assembleMemoryContext(options) {
|
|
|
126
131
|
score: m.score,
|
|
127
132
|
lane,
|
|
128
133
|
...lane === "fact" && { recalled: true },
|
|
129
|
-
sourceIds: m.sourceChunkIds ?? (m.messageId ? [m.messageId] : [])
|
|
134
|
+
sourceIds: m.sourceChunkIds ?? (m.messageId ? [m.messageId] : []),
|
|
135
|
+
...savedAt(m.createdAt)
|
|
130
136
|
}));
|
|
131
137
|
const recalledFacts = toItems(facts, "fact");
|
|
132
138
|
const recalledScores = /* @__PURE__ */ new Map();
|
|
@@ -920,6 +920,9 @@ interface MemoryContextItem {
|
|
|
920
920
|
sourceIds: string[];
|
|
921
921
|
/** Ranked fact evidence, retained when profile deduplication wins placement. */
|
|
922
922
|
recalled?: boolean;
|
|
923
|
+
/** When the memory was written — lets the prompt show a saved date so the
|
|
924
|
+
* model can answer "what did I save recently". */
|
|
925
|
+
createdAt?: Date;
|
|
923
926
|
}
|
|
924
927
|
interface MemoryContextOptions {
|
|
925
928
|
query: string;
|
package/dist/memory/context.d.ts
CHANGED
|
@@ -920,6 +920,9 @@ interface MemoryContextItem {
|
|
|
920
920
|
sourceIds: string[];
|
|
921
921
|
/** Ranked fact evidence, retained when profile deduplication wins placement. */
|
|
922
922
|
recalled?: boolean;
|
|
923
|
+
/** When the memory was written — lets the prompt show a saved date so the
|
|
924
|
+
* model can answer "what did I save recently". */
|
|
925
|
+
createdAt?: Date;
|
|
923
926
|
}
|
|
924
927
|
interface MemoryContextOptions {
|
|
925
928
|
query: string;
|
package/dist/memory/context.mjs
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
// src/lib/memory/context.ts
|
|
2
|
+
function savedAt(createdAt) {
|
|
3
|
+
const ms = createdAt?.getTime();
|
|
4
|
+
return ms !== void 0 && Number.isFinite(ms) && ms > 0 ? { createdAt } : {};
|
|
5
|
+
}
|
|
2
6
|
function shouldRecallMemory(query) {
|
|
3
7
|
const normalized = query.trim().toLowerCase().replace(/[.!?。!?¡¿]+$/u, "").replace(/^[¡¿]+/u, "");
|
|
4
8
|
return normalized.length > 0 && !/^(hi|hi there|hello|hey|yes|no|yep|nope|sure|k|ok|okay|thanks|thank you|thank you very much|thanks a lot|cool|great|got it|sounds good|hola|buenos días|buenas|sí|si|gracias|muchas gracias|vale|bonjour|salut|oui|non|merci|merci beaucoup|d'accord|hallo|guten tag|ja|nein|danke|danke schön|alles klar|olá|obrigado|obrigada|ciao|grazie|sì|你好|谢谢|好的|こんにちは|ありがとう|안녕하세요|감사합니다)$/u.test(
|
|
@@ -36,7 +40,8 @@ async function assembleMemoryContext(options) {
|
|
|
36
40
|
content: m.content,
|
|
37
41
|
score,
|
|
38
42
|
lane,
|
|
39
|
-
sourceIds: m.sourceChunkIds ?? []
|
|
43
|
+
sourceIds: m.sourceChunkIds ?? [],
|
|
44
|
+
...savedAt(m.createdAt)
|
|
40
45
|
});
|
|
41
46
|
const empty = {
|
|
42
47
|
memories: [],
|
|
@@ -101,7 +106,8 @@ async function assembleMemoryContext(options) {
|
|
|
101
106
|
score: m.score,
|
|
102
107
|
lane,
|
|
103
108
|
...lane === "fact" && { recalled: true },
|
|
104
|
-
sourceIds: m.sourceChunkIds ?? (m.messageId ? [m.messageId] : [])
|
|
109
|
+
sourceIds: m.sourceChunkIds ?? (m.messageId ? [m.messageId] : []),
|
|
110
|
+
...savedAt(m.createdAt)
|
|
105
111
|
}));
|
|
106
112
|
const recalledFacts = toItems(facts, "fact");
|
|
107
113
|
const recalledScores = /* @__PURE__ */ new Map();
|