@anuma/sdk 6.40.0 → 6.41.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/expo/index.cjs +132 -67
- package/dist/expo/index.d.mts +26 -1
- package/dist/expo/index.d.ts +26 -1
- package/dist/expo/index.mjs +129 -67
- package/dist/memory/context.d.mts +2 -0
- package/dist/memory/context.d.ts +2 -0
- package/dist/react/index.cjs +94 -27
- package/dist/react/index.d.mts +26 -1
- package/dist/react/index.d.ts +26 -1
- package/dist/react/index.mjs +91 -27
- package/dist/server/index.cjs +71 -24
- package/dist/server/index.d.mts +4 -0
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.mjs +71 -24
- package/package.json +1 -1
package/dist/expo/index.mjs
CHANGED
|
@@ -9333,6 +9333,62 @@ async function clearConversationMemoriesOp(ctx, conversationId) {
|
|
|
9333
9333
|
});
|
|
9334
9334
|
}
|
|
9335
9335
|
|
|
9336
|
+
// src/lib/db/entities/types.ts
|
|
9337
|
+
var ENTITY_KINDS = [
|
|
9338
|
+
"person",
|
|
9339
|
+
"organization",
|
|
9340
|
+
"place",
|
|
9341
|
+
"event",
|
|
9342
|
+
"product",
|
|
9343
|
+
"thing",
|
|
9344
|
+
"concept",
|
|
9345
|
+
"other"
|
|
9346
|
+
];
|
|
9347
|
+
function normalizeEntityName(name) {
|
|
9348
|
+
return name.trim().toLowerCase();
|
|
9349
|
+
}
|
|
9350
|
+
var TOPIC_SALIENCE_WEIGHTS = { primary: 1, secondary: 0.6, mention: 0.3 };
|
|
9351
|
+
function topicWeight(topic) {
|
|
9352
|
+
return topic.source === "user" ? 1 : topic.weight ?? 1;
|
|
9353
|
+
}
|
|
9354
|
+
function primaryTopic(topics) {
|
|
9355
|
+
let best = null;
|
|
9356
|
+
for (const topic of topics ?? []) {
|
|
9357
|
+
if (best === null || topicWeight(topic) > topicWeight(best)) best = topic;
|
|
9358
|
+
}
|
|
9359
|
+
return best;
|
|
9360
|
+
}
|
|
9361
|
+
function parseTopicWeight(value) {
|
|
9362
|
+
return typeof value === "number" && value > 0 && value <= 1 ? value : void 0;
|
|
9363
|
+
}
|
|
9364
|
+
function serializeTopics(topics) {
|
|
9365
|
+
return JSON.stringify(topics);
|
|
9366
|
+
}
|
|
9367
|
+
function parseTopics(value) {
|
|
9368
|
+
if (typeof value !== "string" || value.length === 0) return null;
|
|
9369
|
+
let parsed;
|
|
9370
|
+
try {
|
|
9371
|
+
parsed = JSON.parse(value);
|
|
9372
|
+
} catch {
|
|
9373
|
+
return null;
|
|
9374
|
+
}
|
|
9375
|
+
if (!Array.isArray(parsed)) return null;
|
|
9376
|
+
const out = [];
|
|
9377
|
+
for (const raw of parsed) {
|
|
9378
|
+
if (typeof raw !== "object" || raw === null) continue;
|
|
9379
|
+
const { name, kind, source, weight } = raw;
|
|
9380
|
+
if (typeof name !== "string" || name.trim().length === 0) continue;
|
|
9381
|
+
const parsedWeight = parseTopicWeight(weight);
|
|
9382
|
+
out.push({
|
|
9383
|
+
name,
|
|
9384
|
+
...typeof kind === "string" && kind.length > 0 ? { kind } : {},
|
|
9385
|
+
source: source === "user" ? "user" : "auto",
|
|
9386
|
+
...parsedWeight !== void 0 ? { weight: parsedWeight } : {}
|
|
9387
|
+
});
|
|
9388
|
+
}
|
|
9389
|
+
return out;
|
|
9390
|
+
}
|
|
9391
|
+
|
|
9336
9392
|
// src/lib/db/manager.ts
|
|
9337
9393
|
import { Database } from "@nozbe/watermelondb";
|
|
9338
9394
|
|
|
@@ -10689,48 +10745,6 @@ import { Q as Q5 } from "@nozbe/watermelondb";
|
|
|
10689
10745
|
|
|
10690
10746
|
// src/lib/db/entities/operations.ts
|
|
10691
10747
|
import { Q as Q4 } from "@nozbe/watermelondb";
|
|
10692
|
-
|
|
10693
|
-
// src/lib/db/entities/types.ts
|
|
10694
|
-
var ENTITY_KINDS = [
|
|
10695
|
-
"person",
|
|
10696
|
-
"organization",
|
|
10697
|
-
"place",
|
|
10698
|
-
"event",
|
|
10699
|
-
"product",
|
|
10700
|
-
"thing",
|
|
10701
|
-
"concept",
|
|
10702
|
-
"other"
|
|
10703
|
-
];
|
|
10704
|
-
function normalizeEntityName(name) {
|
|
10705
|
-
return name.trim().toLowerCase();
|
|
10706
|
-
}
|
|
10707
|
-
function serializeTopics(topics) {
|
|
10708
|
-
return JSON.stringify(topics);
|
|
10709
|
-
}
|
|
10710
|
-
function parseTopics(value) {
|
|
10711
|
-
if (typeof value !== "string" || value.length === 0) return null;
|
|
10712
|
-
let parsed;
|
|
10713
|
-
try {
|
|
10714
|
-
parsed = JSON.parse(value);
|
|
10715
|
-
} catch {
|
|
10716
|
-
return null;
|
|
10717
|
-
}
|
|
10718
|
-
if (!Array.isArray(parsed)) return null;
|
|
10719
|
-
const out = [];
|
|
10720
|
-
for (const raw of parsed) {
|
|
10721
|
-
if (typeof raw !== "object" || raw === null) continue;
|
|
10722
|
-
const { name, kind, source } = raw;
|
|
10723
|
-
if (typeof name !== "string" || name.trim().length === 0) continue;
|
|
10724
|
-
out.push({
|
|
10725
|
-
name,
|
|
10726
|
-
...typeof kind === "string" && kind.length > 0 ? { kind } : {},
|
|
10727
|
-
source: source === "user" ? "user" : "auto"
|
|
10728
|
-
});
|
|
10729
|
-
}
|
|
10730
|
-
return out;
|
|
10731
|
-
}
|
|
10732
|
-
|
|
10733
|
-
// src/lib/db/entities/operations.ts
|
|
10734
10748
|
function entityToStored(e) {
|
|
10735
10749
|
return {
|
|
10736
10750
|
uniqueId: e.id,
|
|
@@ -10811,21 +10825,47 @@ function displayNamesOf(entities) {
|
|
|
10811
10825
|
}
|
|
10812
10826
|
function topicsEqual(stored2, computed) {
|
|
10813
10827
|
if (stored2 === null || stored2.length !== computed.length) return false;
|
|
10814
|
-
const key = (t) => JSON.stringify([t.name, t.kind ?? null, t.source]);
|
|
10828
|
+
const key = (t) => JSON.stringify([t.name, t.kind ?? null, t.source, t.weight ?? null]);
|
|
10815
10829
|
const storedKeys = stored2.map(key).sort();
|
|
10816
10830
|
const computedKeys = computed.map(key).sort();
|
|
10817
10831
|
return storedKeys.every((k, i) => k === computedKeys[i]);
|
|
10818
10832
|
}
|
|
10819
|
-
function resolveTopicsWrite(row, linked,
|
|
10833
|
+
function resolveTopicsWrite(row, linked, inputs, source, mode) {
|
|
10820
10834
|
if (row === null || source === null) return null;
|
|
10821
|
-
const
|
|
10822
|
-
|
|
10835
|
+
const stored2 = parseTopics(row.topics);
|
|
10836
|
+
const carried = mode === "merge" ? stored2 : null;
|
|
10837
|
+
const weights = source === "auto" ? weightsOf(carried, inputs) : null;
|
|
10838
|
+
const displayNames = displayNamesOf([...inputs, ...carried ?? []]);
|
|
10839
|
+
const topics = topicsForEntities(linked, displayNames, source, weights);
|
|
10840
|
+
if (topicsEqual(stored2, topics)) return null;
|
|
10823
10841
|
return { row, topics };
|
|
10824
10842
|
}
|
|
10825
|
-
function
|
|
10843
|
+
function weightsOf(stored2, inputs) {
|
|
10844
|
+
const out = /* @__PURE__ */ new Map();
|
|
10845
|
+
for (const topic of stored2 ?? []) out.set(normalizeEntityName(topic.name), topic.weight);
|
|
10846
|
+
for (const input of inputs) {
|
|
10847
|
+
const weight = parseTopicWeight(input.weight);
|
|
10848
|
+
if (weight === void 0) continue;
|
|
10849
|
+
const name = normalizeEntityName(input.name);
|
|
10850
|
+
if (!out.has(name)) {
|
|
10851
|
+
out.set(name, weight);
|
|
10852
|
+
continue;
|
|
10853
|
+
}
|
|
10854
|
+
const current = out.get(name);
|
|
10855
|
+
if (current !== void 0 && weight > current) out.set(name, weight);
|
|
10856
|
+
}
|
|
10857
|
+
return out;
|
|
10858
|
+
}
|
|
10859
|
+
function topicsForEntities(entities, displayNames, source, weights) {
|
|
10826
10860
|
return entities.map((e) => {
|
|
10827
10861
|
const name = displayNames.get(e.canonicalName) ?? e.canonicalName;
|
|
10828
|
-
|
|
10862
|
+
const weight = weights?.get(e.canonicalName);
|
|
10863
|
+
return {
|
|
10864
|
+
name,
|
|
10865
|
+
...e.kind ? { kind: e.kind } : {},
|
|
10866
|
+
source,
|
|
10867
|
+
...weight !== void 0 ? { weight } : {}
|
|
10868
|
+
};
|
|
10829
10869
|
});
|
|
10830
10870
|
}
|
|
10831
10871
|
function toEntityObjects(entityInputs) {
|
|
@@ -10833,7 +10873,7 @@ function toEntityObjects(entityInputs) {
|
|
|
10833
10873
|
}
|
|
10834
10874
|
async function resolveMemoryTopicsWrite(ctx, memoryId, linked, inputs, source) {
|
|
10835
10875
|
const row = await findVaultRowInWrite(ctx, memoryId);
|
|
10836
|
-
return resolveTopicsWrite(row, linked,
|
|
10876
|
+
return resolveTopicsWrite(row, linked, toEntityObjects(inputs), source, "replace");
|
|
10837
10877
|
}
|
|
10838
10878
|
function prepareMemoryTopicsUpdate(write) {
|
|
10839
10879
|
return prepareTopicsUpdate(write.row, write.topics, Date.now());
|
|
@@ -10871,8 +10911,9 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
|
10871
10911
|
const topicsWrite = resolveTopicsWrite(
|
|
10872
10912
|
vaultRow,
|
|
10873
10913
|
[...carriedOver, ...entities],
|
|
10874
|
-
|
|
10875
|
-
options?.topicsSource ?? "auto"
|
|
10914
|
+
normalized,
|
|
10915
|
+
options?.topicsSource ?? "auto",
|
|
10916
|
+
"merge"
|
|
10876
10917
|
);
|
|
10877
10918
|
if (entityOps.length === 0 && kindBackfills.length === 0 && toCreate.length === 0 && topicsWrite === null) {
|
|
10878
10919
|
return;
|
|
@@ -10938,8 +10979,9 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
|
|
|
10938
10979
|
const topicsWrite = resolveTopicsWrite(
|
|
10939
10980
|
vaultRow,
|
|
10940
10981
|
entities,
|
|
10941
|
-
|
|
10942
|
-
options.topicsSource
|
|
10982
|
+
normalized,
|
|
10983
|
+
options.topicsSource,
|
|
10984
|
+
"replace"
|
|
10943
10985
|
);
|
|
10944
10986
|
if (entityOps.length === 0 && kindBackfills.length === 0 && toCreate.length === 0 && toDestroy.length === 0 && topicsWrite === null) {
|
|
10945
10987
|
return;
|
|
@@ -15739,9 +15781,9 @@ For each durable fact, output:
|
|
|
15739
15781
|
- type: one of identity | preference | relationship | plan | ongoing_context | constraint | other
|
|
15740
15782
|
- confidence: 0.0-1.0; how sure you are this is durable AND true. Only include facts >= 0.7.
|
|
15741
15783
|
- sourceMessageIds: which message IDs from the conversation contained the evidence
|
|
15742
|
-
- entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "organization" | "place" | "event" | "product" | "thing" | "concept" | "other" }. Optional \u2014 include only NAMED entities, skip generic/common nouns. ${ENTITY_KIND_GUIDELINES} Examples:
|
|
15743
|
-
- "started a new job at Hollowpoint Labs and I'm learning Haskell for it" \u2192 entities: [{ "name": "Hollowpoint Labs", "kind": "organization" }, { "name": "Haskell", "kind": "concept" }]
|
|
15744
|
-
- "running the Berlin Half in May and I track workouts in Whoop" \u2192 entities: [{ "name": "Berlin Half", "kind": "event" }, { "name": "Whoop", "kind": "product" }]
|
|
15784
|
+
- entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "organization" | "place" | "event" | "product" | "thing" | "concept" | "other", "salience": one of "primary" | "secondary" | "mention" }. Optional \u2014 include only NAMED entities, skip generic/common nouns. ${ENTITY_KIND_GUIDELINES} Salience is how central the entity is to the fact: "primary" = the fact is ABOUT it (usually exactly one per fact), "secondary" = a meaningful part of it, "mention" = named in passing. Examples:
|
|
15785
|
+
- "started a new job at Hollowpoint Labs and I'm learning Haskell for it" \u2192 entities: [{ "name": "Hollowpoint Labs", "kind": "organization", "salience": "primary" }, { "name": "Haskell", "kind": "concept", "salience": "secondary" }]
|
|
15786
|
+
- "running the Berlin Half in May and I track workouts in Whoop" \u2192 entities: [{ "name": "Berlin Half", "kind": "event", "salience": "primary" }, { "name": "Whoop", "kind": "product", "salience": "mention" }]
|
|
15745
15787
|
- eventTime: when the event in this fact occurs/occurred. Resolve relative phrases ("yesterday", "next week") against the current date given in the user message. Output one of:
|
|
15746
15788
|
- { "kind": "point", "start": "YYYY-MM-DD" } for a single date ("met Sara on March 14, 2026")
|
|
15747
15789
|
- { "kind": "range", "start": "YYYY-MM-DD", "end": "YYYY-MM-DD" } for a span ("Japan trip May 4\u201315, 2026")
|
|
@@ -15822,9 +15864,10 @@ function restoreCandidates(candidates, redactor, ownNames) {
|
|
|
15822
15864
|
candidate: {
|
|
15823
15865
|
...c,
|
|
15824
15866
|
content: content.text,
|
|
15825
|
-
entities: c.entities.
|
|
15826
|
-
|
|
15827
|
-
|
|
15867
|
+
entities: c.entities.flatMap((e) => {
|
|
15868
|
+
const restored = redactor.restoreForStorage(e.name);
|
|
15869
|
+
return restored.unresolved ? [] : [{ ...e, name: restored.text }];
|
|
15870
|
+
})
|
|
15828
15871
|
},
|
|
15829
15872
|
unresolved: content.unresolved
|
|
15830
15873
|
};
|
|
@@ -16053,7 +16096,12 @@ function parseEntities(raw) {
|
|
|
16053
16096
|
const name = typeof obj.name === "string" ? obj.name.trim() : "";
|
|
16054
16097
|
if (name.length === 0 || isGenericEntityName(name)) continue;
|
|
16055
16098
|
const kind = typeof obj.kind === "string" && ENTITY_KINDS.includes(obj.kind) ? obj.kind : void 0;
|
|
16056
|
-
|
|
16099
|
+
const weight = typeof obj.salience === "string" && Object.keys(TOPIC_SALIENCE_WEIGHTS).includes(obj.salience) ? TOPIC_SALIENCE_WEIGHTS[obj.salience] : void 0;
|
|
16100
|
+
out.push({
|
|
16101
|
+
name,
|
|
16102
|
+
...kind !== void 0 ? { kind } : {},
|
|
16103
|
+
...weight !== void 0 ? { weight } : {}
|
|
16104
|
+
});
|
|
16057
16105
|
}
|
|
16058
16106
|
return out;
|
|
16059
16107
|
}
|
|
@@ -18012,7 +18060,13 @@ Include only NAMED entities, skip generic/common nouns. A topic must identify a
|
|
|
18012
18060
|
- Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
|
|
18013
18061
|
${ENTITY_KIND_GUIDELINES}
|
|
18014
18062
|
|
|
18015
|
-
|
|
18063
|
+
Give each entity a "salience" \u2014 how central it is to the memory:
|
|
18064
|
+
- "primary": the memory is ABOUT it. A memory with entities usually has exactly one primary; never more than two.
|
|
18065
|
+
- "secondary": a meaningful part of the memory, but not its subject.
|
|
18066
|
+
- "mention": named in passing; the memory would say much the same without it.
|
|
18067
|
+
Example: "Ran the Chicago Marathon with my sister Ana in 3:41" \u2192 Chicago Marathon primary, Ana secondary.
|
|
18068
|
+
|
|
18069
|
+
Each memory below is written as "<id>: <text>". Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string, "salience": "primary" | "secondary" | "mention"}]}]}
|
|
18016
18070
|
- exactly one element per input memory; copy its id EXACTLY as written (the token before the first ": "), with no brackets, quotes, or extra characters
|
|
18017
18071
|
- "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
|
|
18018
18072
|
No prose.`;
|
|
@@ -18083,9 +18137,10 @@ List each memory's named entities.`,
|
|
|
18083
18137
|
return out;
|
|
18084
18138
|
}
|
|
18085
18139
|
function restoreEntities(entities, redactor) {
|
|
18086
|
-
return entities.
|
|
18087
|
-
|
|
18088
|
-
|
|
18140
|
+
return entities.flatMap((e) => {
|
|
18141
|
+
const restored = redactor.restoreForStorage(e.name);
|
|
18142
|
+
return restored.unresolved ? [] : [{ ...e, name: restored.text }];
|
|
18143
|
+
});
|
|
18089
18144
|
}
|
|
18090
18145
|
function parseTopicResponse(parsed, validIds) {
|
|
18091
18146
|
if (typeof parsed !== "object" || parsed === null) return null;
|
|
@@ -19372,19 +19427,23 @@ function topicInputs(topics, source) {
|
|
|
19372
19427
|
return topics.flatMap((topic) => {
|
|
19373
19428
|
const name = (typeof topic === "string" ? topic : topic.name).trim();
|
|
19374
19429
|
const kind = typeof topic === "string" ? void 0 : topic.kind;
|
|
19375
|
-
|
|
19430
|
+
const weight = typeof topic === "string" || source === "user" ? void 0 : parseTopicWeight(topic.weight);
|
|
19431
|
+
return name ? [{ name, ...kind && { kind }, source, ...weight && { weight } }] : [];
|
|
19376
19432
|
});
|
|
19377
19433
|
}
|
|
19378
19434
|
function mergeTopics(existing, added) {
|
|
19379
19435
|
const byName = /* @__PURE__ */ new Map();
|
|
19380
19436
|
for (const topic of [...existing, ...added]) {
|
|
19381
19437
|
const key = normalizeEntityName(topic.name);
|
|
19382
|
-
|
|
19438
|
+
const kept = byName.get(key);
|
|
19439
|
+
if (!kept) byName.set(key, topic);
|
|
19440
|
+
else if (kept.weight !== void 0 && topic.weight !== void 0 && topic.weight > kept.weight)
|
|
19441
|
+
byName.set(key, { ...kept, weight: topic.weight });
|
|
19383
19442
|
}
|
|
19384
19443
|
return [...byName.values()];
|
|
19385
19444
|
}
|
|
19386
19445
|
function sameTopics(stored2, next) {
|
|
19387
|
-
const key = (t) => JSON.stringify([t.name, t.kind ?? null, t.source]);
|
|
19446
|
+
const key = (t) => JSON.stringify([t.name, t.kind ?? null, t.source, t.weight ?? null]);
|
|
19388
19447
|
if (stored2 === null || stored2.length !== next.length) return false;
|
|
19389
19448
|
const keys = new Set(stored2.map(key));
|
|
19390
19449
|
return next.every((t) => keys.has(key(t)));
|
|
@@ -26296,6 +26355,7 @@ export {
|
|
|
26296
26355
|
TOOL_RESULT_ORIGIN,
|
|
26297
26356
|
TOPICS_EXTRACTION_VERSION,
|
|
26298
26357
|
TOPIC_EXTRACTION_BATCH_SIZE,
|
|
26358
|
+
TOPIC_SALIENCE_WEIGHTS,
|
|
26299
26359
|
TREND_RECENT_WINDOW_DAYS,
|
|
26300
26360
|
TREND_STALE_WINDOW_DAYS,
|
|
26301
26361
|
VAULT_SIZE_HOP_CAP,
|
|
@@ -26420,6 +26480,7 @@ export {
|
|
|
26420
26480
|
onKeyAvailable,
|
|
26421
26481
|
parseMedia,
|
|
26422
26482
|
preEmbedVaultMemories,
|
|
26483
|
+
primaryTopic,
|
|
26423
26484
|
quantizeEmbedding,
|
|
26424
26485
|
queueManager,
|
|
26425
26486
|
rankProfileCandidates,
|
|
@@ -26453,6 +26514,7 @@ export {
|
|
|
26453
26514
|
summarizeObservationTrends,
|
|
26454
26515
|
supersedeVaultMemoryOp,
|
|
26455
26516
|
synthesizeProfile,
|
|
26517
|
+
topicWeight,
|
|
26456
26518
|
traverseGraphLane,
|
|
26457
26519
|
ttlForType,
|
|
26458
26520
|
updateVaultFolderContextOp,
|
|
@@ -157,6 +157,8 @@ interface StoredTopic {
|
|
|
157
157
|
name: string;
|
|
158
158
|
kind?: string;
|
|
159
159
|
source: TopicSource;
|
|
160
|
+
/** How central the topic is to the memory, in (0, 1]; read it with {@link topicWeight}. */
|
|
161
|
+
weight?: number;
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
interface EntityOperationsContext {
|
package/dist/memory/context.d.ts
CHANGED
|
@@ -157,6 +157,8 @@ interface StoredTopic {
|
|
|
157
157
|
name: string;
|
|
158
158
|
kind?: string;
|
|
159
159
|
source: TopicSource;
|
|
160
|
+
/** How central the topic is to the memory, in (0, 1]; read it with {@link topicWeight}. */
|
|
161
|
+
weight?: number;
|
|
160
162
|
}
|
|
161
163
|
|
|
162
164
|
interface EntityOperationsContext {
|
package/dist/react/index.cjs
CHANGED
|
@@ -1463,6 +1463,7 @@ __export(index_exports, {
|
|
|
1463
1463
|
TOOL_RESULT_ORIGIN: () => TOOL_RESULT_ORIGIN,
|
|
1464
1464
|
TOPICS_EXTRACTION_VERSION: () => TOPICS_EXTRACTION_VERSION,
|
|
1465
1465
|
TOPIC_EXTRACTION_BATCH_SIZE: () => TOPIC_EXTRACTION_BATCH_SIZE,
|
|
1466
|
+
TOPIC_SALIENCE_WEIGHTS: () => TOPIC_SALIENCE_WEIGHTS,
|
|
1466
1467
|
TREND_RECENT_WINDOW_DAYS: () => TREND_RECENT_WINDOW_DAYS,
|
|
1467
1468
|
TREND_STALE_WINDOW_DAYS: () => TREND_STALE_WINDOW_DAYS,
|
|
1468
1469
|
TextProcessor: () => TextProcessor,
|
|
@@ -1725,6 +1726,7 @@ __export(index_exports, {
|
|
|
1725
1726
|
preEmbedVaultMemories: () => preEmbedVaultMemories,
|
|
1726
1727
|
preprocessFiles: () => preprocessFiles,
|
|
1727
1728
|
previewToolSelection: () => previewToolSelection,
|
|
1729
|
+
primaryTopic: () => primaryTopic,
|
|
1728
1730
|
projectToStored: () => projectToStored,
|
|
1729
1731
|
putAppFileOp: () => putAppFileOp,
|
|
1730
1732
|
quantizeEmbedding: () => quantizeEmbedding,
|
|
@@ -1798,6 +1800,7 @@ __export(index_exports, {
|
|
|
1798
1800
|
summarizeObservationTrends: () => summarizeObservationTrends,
|
|
1799
1801
|
supersedeVaultMemoryOp: () => supersedeVaultMemoryOp,
|
|
1800
1802
|
synthesizeProfile: () => synthesizeProfile,
|
|
1803
|
+
topicWeight: () => topicWeight,
|
|
1801
1804
|
traverseGraphLane: () => traverseGraphLane,
|
|
1802
1805
|
ttlForType: () => ttlForType,
|
|
1803
1806
|
updateAttrs: () => updateAttrs,
|
|
@@ -12951,6 +12954,20 @@ var ENTITY_KINDS = [
|
|
|
12951
12954
|
function normalizeEntityName(name) {
|
|
12952
12955
|
return name.trim().toLowerCase();
|
|
12953
12956
|
}
|
|
12957
|
+
var TOPIC_SALIENCE_WEIGHTS = { primary: 1, secondary: 0.6, mention: 0.3 };
|
|
12958
|
+
function topicWeight(topic) {
|
|
12959
|
+
return topic.source === "user" ? 1 : topic.weight ?? 1;
|
|
12960
|
+
}
|
|
12961
|
+
function primaryTopic(topics) {
|
|
12962
|
+
let best = null;
|
|
12963
|
+
for (const topic of topics ?? []) {
|
|
12964
|
+
if (best === null || topicWeight(topic) > topicWeight(best)) best = topic;
|
|
12965
|
+
}
|
|
12966
|
+
return best;
|
|
12967
|
+
}
|
|
12968
|
+
function parseTopicWeight(value) {
|
|
12969
|
+
return typeof value === "number" && value > 0 && value <= 1 ? value : void 0;
|
|
12970
|
+
}
|
|
12954
12971
|
function serializeTopics(topics) {
|
|
12955
12972
|
return JSON.stringify(topics);
|
|
12956
12973
|
}
|
|
@@ -12966,12 +12983,14 @@ function parseTopics(value) {
|
|
|
12966
12983
|
const out = [];
|
|
12967
12984
|
for (const raw of parsed) {
|
|
12968
12985
|
if (typeof raw !== "object" || raw === null) continue;
|
|
12969
|
-
const { name, kind, source } = raw;
|
|
12986
|
+
const { name, kind, source, weight } = raw;
|
|
12970
12987
|
if (typeof name !== "string" || name.trim().length === 0) continue;
|
|
12988
|
+
const parsedWeight = parseTopicWeight(weight);
|
|
12971
12989
|
out.push({
|
|
12972
12990
|
name,
|
|
12973
12991
|
...typeof kind === "string" && kind.length > 0 ? { kind } : {},
|
|
12974
|
-
source: source === "user" ? "user" : "auto"
|
|
12992
|
+
source: source === "user" ? "user" : "auto",
|
|
12993
|
+
...parsedWeight !== void 0 ? { weight: parsedWeight } : {}
|
|
12975
12994
|
});
|
|
12976
12995
|
}
|
|
12977
12996
|
return out;
|
|
@@ -13058,21 +13077,47 @@ function displayNamesOf(entities) {
|
|
|
13058
13077
|
}
|
|
13059
13078
|
function topicsEqual(stored2, computed) {
|
|
13060
13079
|
if (stored2 === null || stored2.length !== computed.length) return false;
|
|
13061
|
-
const key = (t) => JSON.stringify([t.name, t.kind ?? null, t.source]);
|
|
13080
|
+
const key = (t) => JSON.stringify([t.name, t.kind ?? null, t.source, t.weight ?? null]);
|
|
13062
13081
|
const storedKeys = stored2.map(key).sort();
|
|
13063
13082
|
const computedKeys = computed.map(key).sort();
|
|
13064
13083
|
return storedKeys.every((k, i) => k === computedKeys[i]);
|
|
13065
13084
|
}
|
|
13066
|
-
function resolveTopicsWrite(row, linked,
|
|
13085
|
+
function resolveTopicsWrite(row, linked, inputs, source, mode) {
|
|
13067
13086
|
if (row === null || source === null) return null;
|
|
13068
|
-
const
|
|
13069
|
-
|
|
13087
|
+
const stored2 = parseTopics(row.topics);
|
|
13088
|
+
const carried = mode === "merge" ? stored2 : null;
|
|
13089
|
+
const weights = source === "auto" ? weightsOf(carried, inputs) : null;
|
|
13090
|
+
const displayNames = displayNamesOf([...inputs, ...carried ?? []]);
|
|
13091
|
+
const topics = topicsForEntities(linked, displayNames, source, weights);
|
|
13092
|
+
if (topicsEqual(stored2, topics)) return null;
|
|
13070
13093
|
return { row, topics };
|
|
13071
13094
|
}
|
|
13072
|
-
function
|
|
13095
|
+
function weightsOf(stored2, inputs) {
|
|
13096
|
+
const out = /* @__PURE__ */ new Map();
|
|
13097
|
+
for (const topic of stored2 ?? []) out.set(normalizeEntityName(topic.name), topic.weight);
|
|
13098
|
+
for (const input of inputs) {
|
|
13099
|
+
const weight = parseTopicWeight(input.weight);
|
|
13100
|
+
if (weight === void 0) continue;
|
|
13101
|
+
const name = normalizeEntityName(input.name);
|
|
13102
|
+
if (!out.has(name)) {
|
|
13103
|
+
out.set(name, weight);
|
|
13104
|
+
continue;
|
|
13105
|
+
}
|
|
13106
|
+
const current = out.get(name);
|
|
13107
|
+
if (current !== void 0 && weight > current) out.set(name, weight);
|
|
13108
|
+
}
|
|
13109
|
+
return out;
|
|
13110
|
+
}
|
|
13111
|
+
function topicsForEntities(entities, displayNames, source, weights) {
|
|
13073
13112
|
return entities.map((e) => {
|
|
13074
13113
|
const name = displayNames.get(e.canonicalName) ?? e.canonicalName;
|
|
13075
|
-
|
|
13114
|
+
const weight = weights?.get(e.canonicalName);
|
|
13115
|
+
return {
|
|
13116
|
+
name,
|
|
13117
|
+
...e.kind ? { kind: e.kind } : {},
|
|
13118
|
+
source,
|
|
13119
|
+
...weight !== void 0 ? { weight } : {}
|
|
13120
|
+
};
|
|
13076
13121
|
});
|
|
13077
13122
|
}
|
|
13078
13123
|
function toEntityObjects(entityInputs) {
|
|
@@ -13080,7 +13125,7 @@ function toEntityObjects(entityInputs) {
|
|
|
13080
13125
|
}
|
|
13081
13126
|
async function resolveMemoryTopicsWrite(ctx, memoryId, linked, inputs, source) {
|
|
13082
13127
|
const row = await findVaultRowInWrite(ctx, memoryId);
|
|
13083
|
-
return resolveTopicsWrite(row, linked,
|
|
13128
|
+
return resolveTopicsWrite(row, linked, toEntityObjects(inputs), source, "replace");
|
|
13084
13129
|
}
|
|
13085
13130
|
function prepareMemoryTopicsUpdate(write) {
|
|
13086
13131
|
return prepareTopicsUpdate(write.row, write.topics, Date.now());
|
|
@@ -13118,8 +13163,9 @@ async function linkMemoryEntitiesOp(ctx, memoryId, entityInputs, options) {
|
|
|
13118
13163
|
const topicsWrite = resolveTopicsWrite(
|
|
13119
13164
|
vaultRow,
|
|
13120
13165
|
[...carriedOver, ...entities],
|
|
13121
|
-
|
|
13122
|
-
options?.topicsSource ?? "auto"
|
|
13166
|
+
normalized,
|
|
13167
|
+
options?.topicsSource ?? "auto",
|
|
13168
|
+
"merge"
|
|
13123
13169
|
);
|
|
13124
13170
|
if (entityOps.length === 0 && kindBackfills.length === 0 && toCreate.length === 0 && topicsWrite === null) {
|
|
13125
13171
|
return;
|
|
@@ -13185,8 +13231,9 @@ async function replaceMemoryEntities(ctx, memoryId, entityInputs, options) {
|
|
|
13185
13231
|
const topicsWrite = resolveTopicsWrite(
|
|
13186
13232
|
vaultRow,
|
|
13187
13233
|
entities,
|
|
13188
|
-
|
|
13189
|
-
options.topicsSource
|
|
13234
|
+
normalized,
|
|
13235
|
+
options.topicsSource,
|
|
13236
|
+
"replace"
|
|
13190
13237
|
);
|
|
13191
13238
|
if (entityOps.length === 0 && kindBackfills.length === 0 && toCreate.length === 0 && toDestroy.length === 0 && topicsWrite === null) {
|
|
13192
13239
|
return;
|
|
@@ -20719,9 +20766,9 @@ For each durable fact, output:
|
|
|
20719
20766
|
- type: one of identity | preference | relationship | plan | ongoing_context | constraint | other
|
|
20720
20767
|
- confidence: 0.0-1.0; how sure you are this is durable AND true. Only include facts >= 0.7.
|
|
20721
20768
|
- sourceMessageIds: which message IDs from the conversation contained the evidence
|
|
20722
|
-
- entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "organization" | "place" | "event" | "product" | "thing" | "concept" | "other" }. Optional \u2014 include only NAMED entities, skip generic/common nouns. ${ENTITY_KIND_GUIDELINES} Examples:
|
|
20723
|
-
- "started a new job at Hollowpoint Labs and I'm learning Haskell for it" \u2192 entities: [{ "name": "Hollowpoint Labs", "kind": "organization" }, { "name": "Haskell", "kind": "concept" }]
|
|
20724
|
-
- "running the Berlin Half in May and I track workouts in Whoop" \u2192 entities: [{ "name": "Berlin Half", "kind": "event" }, { "name": "Whoop", "kind": "product" }]
|
|
20769
|
+
- entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "organization" | "place" | "event" | "product" | "thing" | "concept" | "other", "salience": one of "primary" | "secondary" | "mention" }. Optional \u2014 include only NAMED entities, skip generic/common nouns. ${ENTITY_KIND_GUIDELINES} Salience is how central the entity is to the fact: "primary" = the fact is ABOUT it (usually exactly one per fact), "secondary" = a meaningful part of it, "mention" = named in passing. Examples:
|
|
20770
|
+
- "started a new job at Hollowpoint Labs and I'm learning Haskell for it" \u2192 entities: [{ "name": "Hollowpoint Labs", "kind": "organization", "salience": "primary" }, { "name": "Haskell", "kind": "concept", "salience": "secondary" }]
|
|
20771
|
+
- "running the Berlin Half in May and I track workouts in Whoop" \u2192 entities: [{ "name": "Berlin Half", "kind": "event", "salience": "primary" }, { "name": "Whoop", "kind": "product", "salience": "mention" }]
|
|
20725
20772
|
- eventTime: when the event in this fact occurs/occurred. Resolve relative phrases ("yesterday", "next week") against the current date given in the user message. Output one of:
|
|
20726
20773
|
- { "kind": "point", "start": "YYYY-MM-DD" } for a single date ("met Sara on March 14, 2026")
|
|
20727
20774
|
- { "kind": "range", "start": "YYYY-MM-DD", "end": "YYYY-MM-DD" } for a span ("Japan trip May 4\u201315, 2026")
|
|
@@ -20802,9 +20849,10 @@ function restoreCandidates(candidates, redactor, ownNames) {
|
|
|
20802
20849
|
candidate: {
|
|
20803
20850
|
...c,
|
|
20804
20851
|
content: content.text,
|
|
20805
|
-
entities: c.entities.
|
|
20806
|
-
|
|
20807
|
-
|
|
20852
|
+
entities: c.entities.flatMap((e) => {
|
|
20853
|
+
const restored = redactor.restoreForStorage(e.name);
|
|
20854
|
+
return restored.unresolved ? [] : [{ ...e, name: restored.text }];
|
|
20855
|
+
})
|
|
20808
20856
|
},
|
|
20809
20857
|
unresolved: content.unresolved
|
|
20810
20858
|
};
|
|
@@ -21033,7 +21081,12 @@ function parseEntities(raw) {
|
|
|
21033
21081
|
const name = typeof obj.name === "string" ? obj.name.trim() : "";
|
|
21034
21082
|
if (name.length === 0 || isGenericEntityName(name)) continue;
|
|
21035
21083
|
const kind = typeof obj.kind === "string" && ENTITY_KINDS.includes(obj.kind) ? obj.kind : void 0;
|
|
21036
|
-
|
|
21084
|
+
const weight = typeof obj.salience === "string" && Object.keys(TOPIC_SALIENCE_WEIGHTS).includes(obj.salience) ? TOPIC_SALIENCE_WEIGHTS[obj.salience] : void 0;
|
|
21085
|
+
out.push({
|
|
21086
|
+
name,
|
|
21087
|
+
...kind !== void 0 ? { kind } : {},
|
|
21088
|
+
...weight !== void 0 ? { weight } : {}
|
|
21089
|
+
});
|
|
21037
21090
|
}
|
|
21038
21091
|
return out;
|
|
21039
21092
|
}
|
|
@@ -23013,7 +23066,13 @@ Include only NAMED entities, skip generic/common nouns. A topic must identify a
|
|
|
23013
23066
|
- Prefer 0 entities over a weak one. A memory whose only candidate is a generic noun has NO entities.
|
|
23014
23067
|
${ENTITY_KIND_GUIDELINES}
|
|
23015
23068
|
|
|
23016
|
-
|
|
23069
|
+
Give each entity a "salience" \u2014 how central it is to the memory:
|
|
23070
|
+
- "primary": the memory is ABOUT it. A memory with entities usually has exactly one primary; never more than two.
|
|
23071
|
+
- "secondary": a meaningful part of the memory, but not its subject.
|
|
23072
|
+
- "mention": named in passing; the memory would say much the same without it.
|
|
23073
|
+
Example: "Ran the Chicago Marathon with my sister Ana in 3:41" \u2192 Chicago Marathon primary, Ana secondary.
|
|
23074
|
+
|
|
23075
|
+
Each memory below is written as "<id>: <text>". Output strict JSON: {"memories": [{"id": string, "entities": [{"name": string, "kind": string, "salience": "primary" | "secondary" | "mention"}]}]}
|
|
23017
23076
|
- exactly one element per input memory; copy its id EXACTLY as written (the token before the first ": "), with no brackets, quotes, or extra characters
|
|
23018
23077
|
- "entities" may be empty when a memory mentions no named entities \u2014 most short memories have 0-3
|
|
23019
23078
|
No prose.`;
|
|
@@ -23084,9 +23143,10 @@ List each memory's named entities.`,
|
|
|
23084
23143
|
return out;
|
|
23085
23144
|
}
|
|
23086
23145
|
function restoreEntities(entities, redactor) {
|
|
23087
|
-
return entities.
|
|
23088
|
-
|
|
23089
|
-
|
|
23146
|
+
return entities.flatMap((e) => {
|
|
23147
|
+
const restored = redactor.restoreForStorage(e.name);
|
|
23148
|
+
return restored.unresolved ? [] : [{ ...e, name: restored.text }];
|
|
23149
|
+
});
|
|
23090
23150
|
}
|
|
23091
23151
|
function parseTopicResponse(parsed, validIds) {
|
|
23092
23152
|
if (typeof parsed !== "object" || parsed === null) return null;
|
|
@@ -24375,19 +24435,23 @@ function topicInputs(topics, source) {
|
|
|
24375
24435
|
return topics.flatMap((topic) => {
|
|
24376
24436
|
const name = (typeof topic === "string" ? topic : topic.name).trim();
|
|
24377
24437
|
const kind = typeof topic === "string" ? void 0 : topic.kind;
|
|
24378
|
-
|
|
24438
|
+
const weight = typeof topic === "string" || source === "user" ? void 0 : parseTopicWeight(topic.weight);
|
|
24439
|
+
return name ? [{ name, ...kind && { kind }, source, ...weight && { weight } }] : [];
|
|
24379
24440
|
});
|
|
24380
24441
|
}
|
|
24381
24442
|
function mergeTopics(existing, added) {
|
|
24382
24443
|
const byName = /* @__PURE__ */ new Map();
|
|
24383
24444
|
for (const topic of [...existing, ...added]) {
|
|
24384
24445
|
const key = normalizeEntityName(topic.name);
|
|
24385
|
-
|
|
24446
|
+
const kept = byName.get(key);
|
|
24447
|
+
if (!kept) byName.set(key, topic);
|
|
24448
|
+
else if (kept.weight !== void 0 && topic.weight !== void 0 && topic.weight > kept.weight)
|
|
24449
|
+
byName.set(key, { ...kept, weight: topic.weight });
|
|
24386
24450
|
}
|
|
24387
24451
|
return [...byName.values()];
|
|
24388
24452
|
}
|
|
24389
24453
|
function sameTopics(stored2, next) {
|
|
24390
|
-
const key = (t) => JSON.stringify([t.name, t.kind ?? null, t.source]);
|
|
24454
|
+
const key = (t) => JSON.stringify([t.name, t.kind ?? null, t.source, t.weight ?? null]);
|
|
24391
24455
|
if (stored2 === null || stored2.length !== next.length) return false;
|
|
24392
24456
|
const keys = new Set(stored2.map(key));
|
|
24393
24457
|
return next.every((t) => keys.has(key(t)));
|
|
@@ -39244,6 +39308,7 @@ function useWalletBinding(options = {}) {
|
|
|
39244
39308
|
TOOL_RESULT_ORIGIN,
|
|
39245
39309
|
TOPICS_EXTRACTION_VERSION,
|
|
39246
39310
|
TOPIC_EXTRACTION_BATCH_SIZE,
|
|
39311
|
+
TOPIC_SALIENCE_WEIGHTS,
|
|
39247
39312
|
TREND_RECENT_WINDOW_DAYS,
|
|
39248
39313
|
TREND_STALE_WINDOW_DAYS,
|
|
39249
39314
|
TextProcessor,
|
|
@@ -39506,6 +39571,7 @@ function useWalletBinding(options = {}) {
|
|
|
39506
39571
|
preEmbedVaultMemories,
|
|
39507
39572
|
preprocessFiles,
|
|
39508
39573
|
previewToolSelection,
|
|
39574
|
+
primaryTopic,
|
|
39509
39575
|
projectToStored,
|
|
39510
39576
|
putAppFileOp,
|
|
39511
39577
|
quantizeEmbedding,
|
|
@@ -39579,6 +39645,7 @@ function useWalletBinding(options = {}) {
|
|
|
39579
39645
|
summarizeObservationTrends,
|
|
39580
39646
|
supersedeVaultMemoryOp,
|
|
39581
39647
|
synthesizeProfile,
|
|
39648
|
+
topicWeight,
|
|
39582
39649
|
traverseGraphLane,
|
|
39583
39650
|
ttlForType,
|
|
39584
39651
|
updateAttrs,
|