@anuma/sdk 1.3.0 → 1.4.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/{chunk-IKPPX3GY.mjs → chunk-QKF7PRL5.mjs} +11 -2
- package/dist/expo/index.cjs +60 -28
- package/dist/expo/index.d.mts +17 -6
- package/dist/expo/index.d.ts +17 -6
- package/dist/expo/index.mjs +51 -28
- package/dist/expo/{recall-4JTNZBAW.mjs → recall-YKNVP2DF.mjs} +1 -1
- package/dist/react/{chunk-KQZ4KVYY.mjs → chunk-SEZCFG24.mjs} +11 -2
- package/dist/react/index.cjs +60 -28
- package/dist/react/index.d.mts +17 -6
- package/dist/react/index.d.ts +17 -6
- package/dist/react/index.mjs +51 -28
- package/dist/react/{recall-Z2HUBS2Y.mjs → recall-UWH5HU6V.mjs} +1 -1
- package/dist/server/{chunk-KLJBJWWI.mjs → chunk-Z7CJGOTG.mjs} +11 -2
- package/dist/server/index.cjs +60 -28
- package/dist/server/index.d.mts +17 -6
- package/dist/server/index.d.ts +17 -6
- package/dist/server/index.mjs +51 -28
- package/dist/server/{recall-IF2HX7ZA.mjs → recall-24ZIA2VL.mjs} +1 -1
- package/package.json +1 -1
|
@@ -1596,7 +1596,16 @@ function makeSyntheticStoredConversation(opts, defaultTitle) {
|
|
|
1596
1596
|
import { Q as Q2 } from "@nozbe/watermelondb";
|
|
1597
1597
|
|
|
1598
1598
|
// src/lib/db/entities/types.ts
|
|
1599
|
-
var ENTITY_KINDS = [
|
|
1599
|
+
var ENTITY_KINDS = [
|
|
1600
|
+
"person",
|
|
1601
|
+
"organization",
|
|
1602
|
+
"place",
|
|
1603
|
+
"event",
|
|
1604
|
+
"product",
|
|
1605
|
+
"thing",
|
|
1606
|
+
"concept",
|
|
1607
|
+
"other"
|
|
1608
|
+
];
|
|
1600
1609
|
function normalizeEntityName(name) {
|
|
1601
1610
|
return name.trim().toLowerCase();
|
|
1602
1611
|
}
|
|
@@ -4680,7 +4689,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
4680
4689
|
legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
|
|
4681
4690
|
);
|
|
4682
4691
|
}
|
|
4683
|
-
const { recall: recall2 } = await import("./recall-
|
|
4692
|
+
const { recall: recall2 } = await import("./recall-YKNVP2DF.mjs");
|
|
4684
4693
|
const result = await recall2(
|
|
4685
4694
|
query,
|
|
4686
4695
|
{ vaultCtx, embeddingOptions, vaultCache: cache },
|
package/dist/expo/index.cjs
CHANGED
|
@@ -3833,7 +3833,16 @@ var ENTITY_KINDS;
|
|
|
3833
3833
|
var init_types3 = __esm({
|
|
3834
3834
|
"src/lib/db/entities/types.ts"() {
|
|
3835
3835
|
"use strict";
|
|
3836
|
-
ENTITY_KINDS = [
|
|
3836
|
+
ENTITY_KINDS = [
|
|
3837
|
+
"person",
|
|
3838
|
+
"organization",
|
|
3839
|
+
"place",
|
|
3840
|
+
"event",
|
|
3841
|
+
"product",
|
|
3842
|
+
"thing",
|
|
3843
|
+
"concept",
|
|
3844
|
+
"other"
|
|
3845
|
+
];
|
|
3837
3846
|
}
|
|
3838
3847
|
});
|
|
3839
3848
|
|
|
@@ -12809,7 +12818,18 @@ For each durable fact, output:
|
|
|
12809
12818
|
- type: one of identity | preference | relationship | plan | ongoing_context | constraint | other
|
|
12810
12819
|
- confidence: 0.0-1.0; how sure you are this is durable AND true. Only include facts >= 0.7.
|
|
12811
12820
|
- sourceMessageIds: which message IDs from the conversation contained the evidence
|
|
12812
|
-
- entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "place" | "thing" | "concept" | "other" }. Optional
|
|
12821
|
+
- 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. Choose the MOST SPECIFIC kind:
|
|
12822
|
+
- person: a named individual ("Sara", "Dr. Lee")
|
|
12823
|
+
- organization: a company, team, school, or group ("Google", "the Warriors", "Stanford")
|
|
12824
|
+
- place: a geographic location or venue ("San Francisco", "Blue Bottle on Valencia")
|
|
12825
|
+
- event: a dated or nameable occurrence ("Chicago Marathon", "the Japan trip", "their wedding")
|
|
12826
|
+
- product: a named app, tool, brand, device, book, film, or other media title ("Linear", "iPhone", "Dune", "Ableton")
|
|
12827
|
+
- thing: a concrete physical object that isn't a branded product ("road bike", "sourdough starter")
|
|
12828
|
+
- concept: a topic, skill, field, language, or idea ("machine learning", "Spanish", "async communication")
|
|
12829
|
+
- other: a named entity that genuinely fits none of the above \u2014 use sparingly
|
|
12830
|
+
Prefer organization / product / event / place over the generic "thing"; fall back to "thing" or "other" only when no specific kind fits. Examples:
|
|
12831
|
+
- "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" }]
|
|
12832
|
+
- "running the Berlin Half in May and I track workouts in Whoop" \u2192 entities: [{ "name": "Berlin Half", "kind": "event" }, { "name": "Whoop", "kind": "product" }]
|
|
12813
12833
|
- 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:
|
|
12814
12834
|
- { "kind": "point", "start": "YYYY-MM-DD" } for a single date ("met Sara on March 14, 2026")
|
|
12815
12835
|
- { "kind": "range", "start": "YYYY-MM-DD", "end": "YYYY-MM-DD" } for a span ("Japan trip May 4\u201315, 2026")
|
|
@@ -16768,8 +16788,18 @@ function getMigrationReloadKey(prefix, walletAddress) {
|
|
|
16768
16788
|
}
|
|
16769
16789
|
var DatabaseManager = class {
|
|
16770
16790
|
constructor(options) {
|
|
16771
|
-
|
|
16772
|
-
|
|
16791
|
+
/**
|
|
16792
|
+
* WatermelonDB instances cached by their derived `dbName` (not by raw wallet
|
|
16793
|
+
* address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
|
|
16794
|
+
* that is requested again — including after a transient `undefined`/guest
|
|
16795
|
+
* excursion or an address that briefly arrives in a different form during
|
|
16796
|
+
* sign-up — reuses the SAME instance instead of being torn down and rebuilt.
|
|
16797
|
+
* The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
|
|
16798
|
+
* (client#4821). Instances are kept for the lifetime of the manager (typically
|
|
16799
|
+
* guest + one wallet); switching wallets keeps prior ones cached rather than
|
|
16800
|
+
* disposing an instance the app may still hold a reference to.
|
|
16801
|
+
*/
|
|
16802
|
+
this.databases = /* @__PURE__ */ new Map();
|
|
16773
16803
|
this.migrationInProgress = false;
|
|
16774
16804
|
this.dbNamePrefix = options.dbNamePrefix;
|
|
16775
16805
|
this.createAdapter = options.createAdapter;
|
|
@@ -16786,8 +16816,9 @@ var DatabaseManager = class {
|
|
|
16786
16816
|
/**
|
|
16787
16817
|
* Get or create a WatermelonDB Database instance for the given wallet.
|
|
16788
16818
|
*
|
|
16789
|
-
*
|
|
16790
|
-
*
|
|
16819
|
+
* Instances are cached per derived dbName and reused across calls (including
|
|
16820
|
+
* repeat/guest-interleaved requests for the same wallet); a new one is built
|
|
16821
|
+
* only for a dbName not yet seen. See the `databases` field for why.
|
|
16791
16822
|
*
|
|
16792
16823
|
* @param walletAddress - The wallet address to scope the database to.
|
|
16793
16824
|
* If undefined, uses a "guest" database.
|
|
@@ -16795,46 +16826,47 @@ var DatabaseManager = class {
|
|
|
16795
16826
|
* @throws If a destructive migration is in progress
|
|
16796
16827
|
*/
|
|
16797
16828
|
getDatabase(walletAddress) {
|
|
16798
|
-
|
|
16799
|
-
|
|
16800
|
-
|
|
16801
|
-
|
|
16802
|
-
to: walletAddress
|
|
16803
|
-
});
|
|
16804
|
-
this.database = null;
|
|
16805
|
-
}
|
|
16806
|
-
if (this.database) {
|
|
16807
|
-
return this.database;
|
|
16829
|
+
const dbName = this.getDbName(walletAddress);
|
|
16830
|
+
const cached = this.databases.get(dbName);
|
|
16831
|
+
if (cached) {
|
|
16832
|
+
return cached;
|
|
16808
16833
|
}
|
|
16809
16834
|
const needsMigration = this.handleSchemaMigration(walletAddress);
|
|
16810
16835
|
if (needsMigration) {
|
|
16811
16836
|
throw new Error("Database migration in progress - app will restart");
|
|
16812
16837
|
}
|
|
16813
|
-
this.currentWalletAddress = walletAddress;
|
|
16814
|
-
const dbName = this.getDbName(walletAddress);
|
|
16815
16838
|
this.logger.debug?.("Initializing database", {
|
|
16816
16839
|
component: "DatabaseManager",
|
|
16817
16840
|
dbName,
|
|
16818
16841
|
walletAddress
|
|
16819
16842
|
});
|
|
16820
16843
|
const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
|
|
16821
|
-
|
|
16844
|
+
const database = new import_watermelondb20.Database({
|
|
16822
16845
|
adapter,
|
|
16823
16846
|
modelClasses: sdkModelClasses
|
|
16824
16847
|
});
|
|
16825
|
-
|
|
16848
|
+
this.databases.set(dbName, database);
|
|
16849
|
+
return database;
|
|
16826
16850
|
}
|
|
16827
16851
|
/**
|
|
16828
|
-
* Reset
|
|
16852
|
+
* Reset ALL cached databases (useful for logout or testing).
|
|
16829
16853
|
*/
|
|
16830
16854
|
async resetDatabase() {
|
|
16831
|
-
const
|
|
16832
|
-
|
|
16833
|
-
|
|
16834
|
-
await db.
|
|
16835
|
-
|
|
16836
|
-
|
|
16837
|
-
|
|
16855
|
+
const errors = [];
|
|
16856
|
+
for (const [dbName, db] of [...this.databases.entries()]) {
|
|
16857
|
+
try {
|
|
16858
|
+
await db.write(async () => {
|
|
16859
|
+
await db.unsafeResetDatabase();
|
|
16860
|
+
});
|
|
16861
|
+
this.databases.delete(dbName);
|
|
16862
|
+
} catch (error) {
|
|
16863
|
+
errors.push({ dbName, error });
|
|
16864
|
+
}
|
|
16865
|
+
}
|
|
16866
|
+
if (errors.length > 0) {
|
|
16867
|
+
throw new Error(
|
|
16868
|
+
`Failed to reset ${errors.length} database(s): ${errors.map((e) => e.dbName).join(", ")}`
|
|
16869
|
+
);
|
|
16838
16870
|
}
|
|
16839
16871
|
}
|
|
16840
16872
|
/**
|
package/dist/expo/index.d.mts
CHANGED
|
@@ -4329,7 +4329,7 @@ declare class MemoryEntity extends Model {
|
|
|
4329
4329
|
* can't drift apart.
|
|
4330
4330
|
* @public
|
|
4331
4331
|
*/
|
|
4332
|
-
declare const ENTITY_KINDS: readonly ["person", "place", "thing", "concept", "other"];
|
|
4332
|
+
declare const ENTITY_KINDS: readonly ["person", "organization", "place", "event", "product", "thing", "concept", "other"];
|
|
4333
4333
|
/** @public */
|
|
4334
4334
|
type EntityKind = (typeof ENTITY_KINDS)[number];
|
|
4335
4335
|
|
|
@@ -6542,8 +6542,18 @@ interface DatabaseManagerOptions {
|
|
|
6542
6542
|
* ```
|
|
6543
6543
|
*/
|
|
6544
6544
|
declare class DatabaseManager {
|
|
6545
|
-
|
|
6546
|
-
|
|
6545
|
+
/**
|
|
6546
|
+
* WatermelonDB instances cached by their derived `dbName` (not by raw wallet
|
|
6547
|
+
* address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
|
|
6548
|
+
* that is requested again — including after a transient `undefined`/guest
|
|
6549
|
+
* excursion or an address that briefly arrives in a different form during
|
|
6550
|
+
* sign-up — reuses the SAME instance instead of being torn down and rebuilt.
|
|
6551
|
+
* The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
|
|
6552
|
+
* (client#4821). Instances are kept for the lifetime of the manager (typically
|
|
6553
|
+
* guest + one wallet); switching wallets keeps prior ones cached rather than
|
|
6554
|
+
* disposing an instance the app may still hold a reference to.
|
|
6555
|
+
*/
|
|
6556
|
+
private readonly databases;
|
|
6547
6557
|
private migrationInProgress;
|
|
6548
6558
|
private readonly dbNamePrefix;
|
|
6549
6559
|
private readonly createAdapter;
|
|
@@ -6558,8 +6568,9 @@ declare class DatabaseManager {
|
|
|
6558
6568
|
/**
|
|
6559
6569
|
* Get or create a WatermelonDB Database instance for the given wallet.
|
|
6560
6570
|
*
|
|
6561
|
-
*
|
|
6562
|
-
*
|
|
6571
|
+
* Instances are cached per derived dbName and reused across calls (including
|
|
6572
|
+
* repeat/guest-interleaved requests for the same wallet); a new one is built
|
|
6573
|
+
* only for a dbName not yet seen. See the `databases` field for why.
|
|
6563
6574
|
*
|
|
6564
6575
|
* @param walletAddress - The wallet address to scope the database to.
|
|
6565
6576
|
* If undefined, uses a "guest" database.
|
|
@@ -6568,7 +6579,7 @@ declare class DatabaseManager {
|
|
|
6568
6579
|
*/
|
|
6569
6580
|
getDatabase(walletAddress?: string): Database;
|
|
6570
6581
|
/**
|
|
6571
|
-
* Reset
|
|
6582
|
+
* Reset ALL cached databases (useful for logout or testing).
|
|
6572
6583
|
*/
|
|
6573
6584
|
resetDatabase(): Promise<void>;
|
|
6574
6585
|
/**
|
package/dist/expo/index.d.ts
CHANGED
|
@@ -4329,7 +4329,7 @@ declare class MemoryEntity extends Model {
|
|
|
4329
4329
|
* can't drift apart.
|
|
4330
4330
|
* @public
|
|
4331
4331
|
*/
|
|
4332
|
-
declare const ENTITY_KINDS: readonly ["person", "place", "thing", "concept", "other"];
|
|
4332
|
+
declare const ENTITY_KINDS: readonly ["person", "organization", "place", "event", "product", "thing", "concept", "other"];
|
|
4333
4333
|
/** @public */
|
|
4334
4334
|
type EntityKind = (typeof ENTITY_KINDS)[number];
|
|
4335
4335
|
|
|
@@ -6542,8 +6542,18 @@ interface DatabaseManagerOptions {
|
|
|
6542
6542
|
* ```
|
|
6543
6543
|
*/
|
|
6544
6544
|
declare class DatabaseManager {
|
|
6545
|
-
|
|
6546
|
-
|
|
6545
|
+
/**
|
|
6546
|
+
* WatermelonDB instances cached by their derived `dbName` (not by raw wallet
|
|
6547
|
+
* address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
|
|
6548
|
+
* that is requested again — including after a transient `undefined`/guest
|
|
6549
|
+
* excursion or an address that briefly arrives in a different form during
|
|
6550
|
+
* sign-up — reuses the SAME instance instead of being torn down and rebuilt.
|
|
6551
|
+
* The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
|
|
6552
|
+
* (client#4821). Instances are kept for the lifetime of the manager (typically
|
|
6553
|
+
* guest + one wallet); switching wallets keeps prior ones cached rather than
|
|
6554
|
+
* disposing an instance the app may still hold a reference to.
|
|
6555
|
+
*/
|
|
6556
|
+
private readonly databases;
|
|
6547
6557
|
private migrationInProgress;
|
|
6548
6558
|
private readonly dbNamePrefix;
|
|
6549
6559
|
private readonly createAdapter;
|
|
@@ -6558,8 +6568,9 @@ declare class DatabaseManager {
|
|
|
6558
6568
|
/**
|
|
6559
6569
|
* Get or create a WatermelonDB Database instance for the given wallet.
|
|
6560
6570
|
*
|
|
6561
|
-
*
|
|
6562
|
-
*
|
|
6571
|
+
* Instances are cached per derived dbName and reused across calls (including
|
|
6572
|
+
* repeat/guest-interleaved requests for the same wallet); a new one is built
|
|
6573
|
+
* only for a dbName not yet seen. See the `databases` field for why.
|
|
6563
6574
|
*
|
|
6564
6575
|
* @param walletAddress - The wallet address to scope the database to.
|
|
6565
6576
|
* If undefined, uses a "guest" database.
|
|
@@ -6568,7 +6579,7 @@ declare class DatabaseManager {
|
|
|
6568
6579
|
*/
|
|
6569
6580
|
getDatabase(walletAddress?: string): Database;
|
|
6570
6581
|
/**
|
|
6571
|
-
* Reset
|
|
6582
|
+
* Reset ALL cached databases (useful for logout or testing).
|
|
6572
6583
|
*/
|
|
6573
6584
|
resetDatabase(): Promise<void>;
|
|
6574
6585
|
/**
|
package/dist/expo/index.mjs
CHANGED
|
@@ -79,7 +79,7 @@ import {
|
|
|
79
79
|
updateVaultMemoryOp,
|
|
80
80
|
upsertMessageOp,
|
|
81
81
|
useEncryption
|
|
82
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-QKF7PRL5.mjs";
|
|
83
83
|
import {
|
|
84
84
|
PII_PATTERNS,
|
|
85
85
|
PiiRedactor,
|
|
@@ -6094,7 +6094,18 @@ For each durable fact, output:
|
|
|
6094
6094
|
- type: one of identity | preference | relationship | plan | ongoing_context | constraint | other
|
|
6095
6095
|
- confidence: 0.0-1.0; how sure you are this is durable AND true. Only include facts >= 0.7.
|
|
6096
6096
|
- sourceMessageIds: which message IDs from the conversation contained the evidence
|
|
6097
|
-
- entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "place" | "thing" | "concept" | "other" }. Optional
|
|
6097
|
+
- 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. Choose the MOST SPECIFIC kind:
|
|
6098
|
+
- person: a named individual ("Sara", "Dr. Lee")
|
|
6099
|
+
- organization: a company, team, school, or group ("Google", "the Warriors", "Stanford")
|
|
6100
|
+
- place: a geographic location or venue ("San Francisco", "Blue Bottle on Valencia")
|
|
6101
|
+
- event: a dated or nameable occurrence ("Chicago Marathon", "the Japan trip", "their wedding")
|
|
6102
|
+
- product: a named app, tool, brand, device, book, film, or other media title ("Linear", "iPhone", "Dune", "Ableton")
|
|
6103
|
+
- thing: a concrete physical object that isn't a branded product ("road bike", "sourdough starter")
|
|
6104
|
+
- concept: a topic, skill, field, language, or idea ("machine learning", "Spanish", "async communication")
|
|
6105
|
+
- other: a named entity that genuinely fits none of the above \u2014 use sparingly
|
|
6106
|
+
Prefer organization / product / event / place over the generic "thing"; fall back to "thing" or "other" only when no specific kind fits. Examples:
|
|
6107
|
+
- "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" }]
|
|
6108
|
+
- "running the Berlin Half in May and I track workouts in Whoop" \u2192 entities: [{ "name": "Berlin Half", "kind": "event" }, { "name": "Whoop", "kind": "product" }]
|
|
6098
6109
|
- 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:
|
|
6099
6110
|
- { "kind": "point", "start": "YYYY-MM-DD" } for a single date ("met Sara on March 14, 2026")
|
|
6100
6111
|
- { "kind": "range", "start": "YYYY-MM-DD", "end": "YYYY-MM-DD" } for a span ("Japan trip May 4\u201315, 2026")
|
|
@@ -10020,8 +10031,18 @@ function getMigrationReloadKey(prefix, walletAddress) {
|
|
|
10020
10031
|
}
|
|
10021
10032
|
var DatabaseManager = class {
|
|
10022
10033
|
constructor(options) {
|
|
10023
|
-
|
|
10024
|
-
|
|
10034
|
+
/**
|
|
10035
|
+
* WatermelonDB instances cached by their derived `dbName` (not by raw wallet
|
|
10036
|
+
* address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
|
|
10037
|
+
* that is requested again — including after a transient `undefined`/guest
|
|
10038
|
+
* excursion or an address that briefly arrives in a different form during
|
|
10039
|
+
* sign-up — reuses the SAME instance instead of being torn down and rebuilt.
|
|
10040
|
+
* The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
|
|
10041
|
+
* (client#4821). Instances are kept for the lifetime of the manager (typically
|
|
10042
|
+
* guest + one wallet); switching wallets keeps prior ones cached rather than
|
|
10043
|
+
* disposing an instance the app may still hold a reference to.
|
|
10044
|
+
*/
|
|
10045
|
+
this.databases = /* @__PURE__ */ new Map();
|
|
10025
10046
|
this.migrationInProgress = false;
|
|
10026
10047
|
this.dbNamePrefix = options.dbNamePrefix;
|
|
10027
10048
|
this.createAdapter = options.createAdapter;
|
|
@@ -10038,8 +10059,9 @@ var DatabaseManager = class {
|
|
|
10038
10059
|
/**
|
|
10039
10060
|
* Get or create a WatermelonDB Database instance for the given wallet.
|
|
10040
10061
|
*
|
|
10041
|
-
*
|
|
10042
|
-
*
|
|
10062
|
+
* Instances are cached per derived dbName and reused across calls (including
|
|
10063
|
+
* repeat/guest-interleaved requests for the same wallet); a new one is built
|
|
10064
|
+
* only for a dbName not yet seen. See the `databases` field for why.
|
|
10043
10065
|
*
|
|
10044
10066
|
* @param walletAddress - The wallet address to scope the database to.
|
|
10045
10067
|
* If undefined, uses a "guest" database.
|
|
@@ -10047,46 +10069,47 @@ var DatabaseManager = class {
|
|
|
10047
10069
|
* @throws If a destructive migration is in progress
|
|
10048
10070
|
*/
|
|
10049
10071
|
getDatabase(walletAddress) {
|
|
10050
|
-
|
|
10051
|
-
|
|
10052
|
-
|
|
10053
|
-
|
|
10054
|
-
to: walletAddress
|
|
10055
|
-
});
|
|
10056
|
-
this.database = null;
|
|
10057
|
-
}
|
|
10058
|
-
if (this.database) {
|
|
10059
|
-
return this.database;
|
|
10072
|
+
const dbName = this.getDbName(walletAddress);
|
|
10073
|
+
const cached = this.databases.get(dbName);
|
|
10074
|
+
if (cached) {
|
|
10075
|
+
return cached;
|
|
10060
10076
|
}
|
|
10061
10077
|
const needsMigration = this.handleSchemaMigration(walletAddress);
|
|
10062
10078
|
if (needsMigration) {
|
|
10063
10079
|
throw new Error("Database migration in progress - app will restart");
|
|
10064
10080
|
}
|
|
10065
|
-
this.currentWalletAddress = walletAddress;
|
|
10066
|
-
const dbName = this.getDbName(walletAddress);
|
|
10067
10081
|
this.logger.debug?.("Initializing database", {
|
|
10068
10082
|
component: "DatabaseManager",
|
|
10069
10083
|
dbName,
|
|
10070
10084
|
walletAddress
|
|
10071
10085
|
});
|
|
10072
10086
|
const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
|
|
10073
|
-
|
|
10087
|
+
const database = new Database({
|
|
10074
10088
|
adapter,
|
|
10075
10089
|
modelClasses: sdkModelClasses
|
|
10076
10090
|
});
|
|
10077
|
-
|
|
10091
|
+
this.databases.set(dbName, database);
|
|
10092
|
+
return database;
|
|
10078
10093
|
}
|
|
10079
10094
|
/**
|
|
10080
|
-
* Reset
|
|
10095
|
+
* Reset ALL cached databases (useful for logout or testing).
|
|
10081
10096
|
*/
|
|
10082
10097
|
async resetDatabase() {
|
|
10083
|
-
const
|
|
10084
|
-
|
|
10085
|
-
|
|
10086
|
-
await db.
|
|
10087
|
-
|
|
10088
|
-
|
|
10089
|
-
|
|
10098
|
+
const errors = [];
|
|
10099
|
+
for (const [dbName, db] of [...this.databases.entries()]) {
|
|
10100
|
+
try {
|
|
10101
|
+
await db.write(async () => {
|
|
10102
|
+
await db.unsafeResetDatabase();
|
|
10103
|
+
});
|
|
10104
|
+
this.databases.delete(dbName);
|
|
10105
|
+
} catch (error) {
|
|
10106
|
+
errors.push({ dbName, error });
|
|
10107
|
+
}
|
|
10108
|
+
}
|
|
10109
|
+
if (errors.length > 0) {
|
|
10110
|
+
throw new Error(
|
|
10111
|
+
`Failed to reset ${errors.length} database(s): ${errors.map((e) => e.dbName).join(", ")}`
|
|
10112
|
+
);
|
|
10090
10113
|
}
|
|
10091
10114
|
}
|
|
10092
10115
|
/**
|
|
@@ -1730,7 +1730,16 @@ function makeSyntheticStoredConversation(opts, defaultTitle) {
|
|
|
1730
1730
|
import { Q as Q2 } from "@nozbe/watermelondb";
|
|
1731
1731
|
|
|
1732
1732
|
// src/lib/db/entities/types.ts
|
|
1733
|
-
var ENTITY_KINDS = [
|
|
1733
|
+
var ENTITY_KINDS = [
|
|
1734
|
+
"person",
|
|
1735
|
+
"organization",
|
|
1736
|
+
"place",
|
|
1737
|
+
"event",
|
|
1738
|
+
"product",
|
|
1739
|
+
"thing",
|
|
1740
|
+
"concept",
|
|
1741
|
+
"other"
|
|
1742
|
+
];
|
|
1734
1743
|
function normalizeEntityName(name) {
|
|
1735
1744
|
return name.trim().toLowerCase();
|
|
1736
1745
|
}
|
|
@@ -5011,7 +5020,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
5011
5020
|
legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
|
|
5012
5021
|
);
|
|
5013
5022
|
}
|
|
5014
|
-
const { recall: recall2 } = await import("./recall-
|
|
5023
|
+
const { recall: recall2 } = await import("./recall-UWH5HU6V.mjs");
|
|
5015
5024
|
const result = await recall2(
|
|
5016
5025
|
query,
|
|
5017
5026
|
{ vaultCtx, embeddingOptions, vaultCache: cache },
|
package/dist/react/index.cjs
CHANGED
|
@@ -4089,7 +4089,16 @@ var ENTITY_KINDS;
|
|
|
4089
4089
|
var init_types3 = __esm({
|
|
4090
4090
|
"src/lib/db/entities/types.ts"() {
|
|
4091
4091
|
"use strict";
|
|
4092
|
-
ENTITY_KINDS = [
|
|
4092
|
+
ENTITY_KINDS = [
|
|
4093
|
+
"person",
|
|
4094
|
+
"organization",
|
|
4095
|
+
"place",
|
|
4096
|
+
"event",
|
|
4097
|
+
"product",
|
|
4098
|
+
"thing",
|
|
4099
|
+
"concept",
|
|
4100
|
+
"other"
|
|
4101
|
+
];
|
|
4093
4102
|
}
|
|
4094
4103
|
});
|
|
4095
4104
|
|
|
@@ -14158,7 +14167,18 @@ For each durable fact, output:
|
|
|
14158
14167
|
- type: one of identity | preference | relationship | plan | ongoing_context | constraint | other
|
|
14159
14168
|
- confidence: 0.0-1.0; how sure you are this is durable AND true. Only include facts >= 0.7.
|
|
14160
14169
|
- sourceMessageIds: which message IDs from the conversation contained the evidence
|
|
14161
|
-
- entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "place" | "thing" | "concept" | "other" }. Optional
|
|
14170
|
+
- 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. Choose the MOST SPECIFIC kind:
|
|
14171
|
+
- person: a named individual ("Sara", "Dr. Lee")
|
|
14172
|
+
- organization: a company, team, school, or group ("Google", "the Warriors", "Stanford")
|
|
14173
|
+
- place: a geographic location or venue ("San Francisco", "Blue Bottle on Valencia")
|
|
14174
|
+
- event: a dated or nameable occurrence ("Chicago Marathon", "the Japan trip", "their wedding")
|
|
14175
|
+
- product: a named app, tool, brand, device, book, film, or other media title ("Linear", "iPhone", "Dune", "Ableton")
|
|
14176
|
+
- thing: a concrete physical object that isn't a branded product ("road bike", "sourdough starter")
|
|
14177
|
+
- concept: a topic, skill, field, language, or idea ("machine learning", "Spanish", "async communication")
|
|
14178
|
+
- other: a named entity that genuinely fits none of the above \u2014 use sparingly
|
|
14179
|
+
Prefer organization / product / event / place over the generic "thing"; fall back to "thing" or "other" only when no specific kind fits. Examples:
|
|
14180
|
+
- "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" }]
|
|
14181
|
+
- "running the Berlin Half in May and I track workouts in Whoop" \u2192 entities: [{ "name": "Berlin Half", "kind": "event" }, { "name": "Whoop", "kind": "product" }]
|
|
14162
14182
|
- 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:
|
|
14163
14183
|
- { "kind": "point", "start": "YYYY-MM-DD" } for a single date ("met Sara on March 14, 2026")
|
|
14164
14184
|
- { "kind": "range", "start": "YYYY-MM-DD", "end": "YYYY-MM-DD" } for a span ("Japan trip May 4\u201315, 2026")
|
|
@@ -19962,8 +19982,18 @@ function getMigrationReloadKey(prefix, walletAddress) {
|
|
|
19962
19982
|
}
|
|
19963
19983
|
var DatabaseManager = class {
|
|
19964
19984
|
constructor(options) {
|
|
19965
|
-
|
|
19966
|
-
|
|
19985
|
+
/**
|
|
19986
|
+
* WatermelonDB instances cached by their derived `dbName` (not by raw wallet
|
|
19987
|
+
* address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
|
|
19988
|
+
* that is requested again — including after a transient `undefined`/guest
|
|
19989
|
+
* excursion or an address that briefly arrives in a different form during
|
|
19990
|
+
* sign-up — reuses the SAME instance instead of being torn down and rebuilt.
|
|
19991
|
+
* The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
|
|
19992
|
+
* (client#4821). Instances are kept for the lifetime of the manager (typically
|
|
19993
|
+
* guest + one wallet); switching wallets keeps prior ones cached rather than
|
|
19994
|
+
* disposing an instance the app may still hold a reference to.
|
|
19995
|
+
*/
|
|
19996
|
+
this.databases = /* @__PURE__ */ new Map();
|
|
19967
19997
|
this.migrationInProgress = false;
|
|
19968
19998
|
this.dbNamePrefix = options.dbNamePrefix;
|
|
19969
19999
|
this.createAdapter = options.createAdapter;
|
|
@@ -19980,8 +20010,9 @@ var DatabaseManager = class {
|
|
|
19980
20010
|
/**
|
|
19981
20011
|
* Get or create a WatermelonDB Database instance for the given wallet.
|
|
19982
20012
|
*
|
|
19983
|
-
*
|
|
19984
|
-
*
|
|
20013
|
+
* Instances are cached per derived dbName and reused across calls (including
|
|
20014
|
+
* repeat/guest-interleaved requests for the same wallet); a new one is built
|
|
20015
|
+
* only for a dbName not yet seen. See the `databases` field for why.
|
|
19985
20016
|
*
|
|
19986
20017
|
* @param walletAddress - The wallet address to scope the database to.
|
|
19987
20018
|
* If undefined, uses a "guest" database.
|
|
@@ -19989,46 +20020,47 @@ var DatabaseManager = class {
|
|
|
19989
20020
|
* @throws If a destructive migration is in progress
|
|
19990
20021
|
*/
|
|
19991
20022
|
getDatabase(walletAddress) {
|
|
19992
|
-
|
|
19993
|
-
|
|
19994
|
-
|
|
19995
|
-
|
|
19996
|
-
to: walletAddress
|
|
19997
|
-
});
|
|
19998
|
-
this.database = null;
|
|
19999
|
-
}
|
|
20000
|
-
if (this.database) {
|
|
20001
|
-
return this.database;
|
|
20023
|
+
const dbName = this.getDbName(walletAddress);
|
|
20024
|
+
const cached = this.databases.get(dbName);
|
|
20025
|
+
if (cached) {
|
|
20026
|
+
return cached;
|
|
20002
20027
|
}
|
|
20003
20028
|
const needsMigration = this.handleSchemaMigration(walletAddress);
|
|
20004
20029
|
if (needsMigration) {
|
|
20005
20030
|
throw new Error("Database migration in progress - app will restart");
|
|
20006
20031
|
}
|
|
20007
|
-
this.currentWalletAddress = walletAddress;
|
|
20008
|
-
const dbName = this.getDbName(walletAddress);
|
|
20009
20032
|
this.logger.debug?.("Initializing database", {
|
|
20010
20033
|
component: "DatabaseManager",
|
|
20011
20034
|
dbName,
|
|
20012
20035
|
walletAddress
|
|
20013
20036
|
});
|
|
20014
20037
|
const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
|
|
20015
|
-
|
|
20038
|
+
const database = new import_watermelondb21.Database({
|
|
20016
20039
|
adapter,
|
|
20017
20040
|
modelClasses: sdkModelClasses
|
|
20018
20041
|
});
|
|
20019
|
-
|
|
20042
|
+
this.databases.set(dbName, database);
|
|
20043
|
+
return database;
|
|
20020
20044
|
}
|
|
20021
20045
|
/**
|
|
20022
|
-
* Reset
|
|
20046
|
+
* Reset ALL cached databases (useful for logout or testing).
|
|
20023
20047
|
*/
|
|
20024
20048
|
async resetDatabase() {
|
|
20025
|
-
const
|
|
20026
|
-
|
|
20027
|
-
|
|
20028
|
-
await db.
|
|
20029
|
-
|
|
20030
|
-
|
|
20031
|
-
|
|
20049
|
+
const errors = [];
|
|
20050
|
+
for (const [dbName, db] of [...this.databases.entries()]) {
|
|
20051
|
+
try {
|
|
20052
|
+
await db.write(async () => {
|
|
20053
|
+
await db.unsafeResetDatabase();
|
|
20054
|
+
});
|
|
20055
|
+
this.databases.delete(dbName);
|
|
20056
|
+
} catch (error) {
|
|
20057
|
+
errors.push({ dbName, error });
|
|
20058
|
+
}
|
|
20059
|
+
}
|
|
20060
|
+
if (errors.length > 0) {
|
|
20061
|
+
throw new Error(
|
|
20062
|
+
`Failed to reset ${errors.length} database(s): ${errors.map((e) => e.dbName).join(", ")}`
|
|
20063
|
+
);
|
|
20032
20064
|
}
|
|
20033
20065
|
}
|
|
20034
20066
|
/**
|
package/dist/react/index.d.mts
CHANGED
|
@@ -5552,7 +5552,7 @@ declare class MemoryEntity extends Model {
|
|
|
5552
5552
|
* can't drift apart.
|
|
5553
5553
|
* @public
|
|
5554
5554
|
*/
|
|
5555
|
-
declare const ENTITY_KINDS: readonly ["person", "place", "thing", "concept", "other"];
|
|
5555
|
+
declare const ENTITY_KINDS: readonly ["person", "organization", "place", "event", "product", "thing", "concept", "other"];
|
|
5556
5556
|
/** @public */
|
|
5557
5557
|
type EntityKind = (typeof ENTITY_KINDS)[number];
|
|
5558
5558
|
interface StoredEntity {
|
|
@@ -8077,8 +8077,18 @@ declare const webPlatformStorage: PlatformStorage;
|
|
|
8077
8077
|
* ```
|
|
8078
8078
|
*/
|
|
8079
8079
|
declare class DatabaseManager {
|
|
8080
|
-
|
|
8081
|
-
|
|
8080
|
+
/**
|
|
8081
|
+
* WatermelonDB instances cached by their derived `dbName` (not by raw wallet
|
|
8082
|
+
* address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
|
|
8083
|
+
* that is requested again — including after a transient `undefined`/guest
|
|
8084
|
+
* excursion or an address that briefly arrives in a different form during
|
|
8085
|
+
* sign-up — reuses the SAME instance instead of being torn down and rebuilt.
|
|
8086
|
+
* The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
|
|
8087
|
+
* (client#4821). Instances are kept for the lifetime of the manager (typically
|
|
8088
|
+
* guest + one wallet); switching wallets keeps prior ones cached rather than
|
|
8089
|
+
* disposing an instance the app may still hold a reference to.
|
|
8090
|
+
*/
|
|
8091
|
+
private readonly databases;
|
|
8082
8092
|
private migrationInProgress;
|
|
8083
8093
|
private readonly dbNamePrefix;
|
|
8084
8094
|
private readonly createAdapter;
|
|
@@ -8093,8 +8103,9 @@ declare class DatabaseManager {
|
|
|
8093
8103
|
/**
|
|
8094
8104
|
* Get or create a WatermelonDB Database instance for the given wallet.
|
|
8095
8105
|
*
|
|
8096
|
-
*
|
|
8097
|
-
*
|
|
8106
|
+
* Instances are cached per derived dbName and reused across calls (including
|
|
8107
|
+
* repeat/guest-interleaved requests for the same wallet); a new one is built
|
|
8108
|
+
* only for a dbName not yet seen. See the `databases` field for why.
|
|
8098
8109
|
*
|
|
8099
8110
|
* @param walletAddress - The wallet address to scope the database to.
|
|
8100
8111
|
* If undefined, uses a "guest" database.
|
|
@@ -8103,7 +8114,7 @@ declare class DatabaseManager {
|
|
|
8103
8114
|
*/
|
|
8104
8115
|
getDatabase(walletAddress?: string): Database;
|
|
8105
8116
|
/**
|
|
8106
|
-
* Reset
|
|
8117
|
+
* Reset ALL cached databases (useful for logout or testing).
|
|
8107
8118
|
*/
|
|
8108
8119
|
resetDatabase(): Promise<void>;
|
|
8109
8120
|
/**
|
package/dist/react/index.d.ts
CHANGED
|
@@ -5552,7 +5552,7 @@ declare class MemoryEntity extends Model {
|
|
|
5552
5552
|
* can't drift apart.
|
|
5553
5553
|
* @public
|
|
5554
5554
|
*/
|
|
5555
|
-
declare const ENTITY_KINDS: readonly ["person", "place", "thing", "concept", "other"];
|
|
5555
|
+
declare const ENTITY_KINDS: readonly ["person", "organization", "place", "event", "product", "thing", "concept", "other"];
|
|
5556
5556
|
/** @public */
|
|
5557
5557
|
type EntityKind = (typeof ENTITY_KINDS)[number];
|
|
5558
5558
|
interface StoredEntity {
|
|
@@ -8077,8 +8077,18 @@ declare const webPlatformStorage: PlatformStorage;
|
|
|
8077
8077
|
* ```
|
|
8078
8078
|
*/
|
|
8079
8079
|
declare class DatabaseManager {
|
|
8080
|
-
|
|
8081
|
-
|
|
8080
|
+
/**
|
|
8081
|
+
* WatermelonDB instances cached by their derived `dbName` (not by raw wallet
|
|
8082
|
+
* address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
|
|
8083
|
+
* that is requested again — including after a transient `undefined`/guest
|
|
8084
|
+
* excursion or an address that briefly arrives in a different form during
|
|
8085
|
+
* sign-up — reuses the SAME instance instead of being torn down and rebuilt.
|
|
8086
|
+
* The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
|
|
8087
|
+
* (client#4821). Instances are kept for the lifetime of the manager (typically
|
|
8088
|
+
* guest + one wallet); switching wallets keeps prior ones cached rather than
|
|
8089
|
+
* disposing an instance the app may still hold a reference to.
|
|
8090
|
+
*/
|
|
8091
|
+
private readonly databases;
|
|
8082
8092
|
private migrationInProgress;
|
|
8083
8093
|
private readonly dbNamePrefix;
|
|
8084
8094
|
private readonly createAdapter;
|
|
@@ -8093,8 +8103,9 @@ declare class DatabaseManager {
|
|
|
8093
8103
|
/**
|
|
8094
8104
|
* Get or create a WatermelonDB Database instance for the given wallet.
|
|
8095
8105
|
*
|
|
8096
|
-
*
|
|
8097
|
-
*
|
|
8106
|
+
* Instances are cached per derived dbName and reused across calls (including
|
|
8107
|
+
* repeat/guest-interleaved requests for the same wallet); a new one is built
|
|
8108
|
+
* only for a dbName not yet seen. See the `databases` field for why.
|
|
8098
8109
|
*
|
|
8099
8110
|
* @param walletAddress - The wallet address to scope the database to.
|
|
8100
8111
|
* If undefined, uses a "guest" database.
|
|
@@ -8103,7 +8114,7 @@ declare class DatabaseManager {
|
|
|
8103
8114
|
*/
|
|
8104
8115
|
getDatabase(walletAddress?: string): Database;
|
|
8105
8116
|
/**
|
|
8106
|
-
* Reset
|
|
8117
|
+
* Reset ALL cached databases (useful for logout or testing).
|
|
8107
8118
|
*/
|
|
8108
8119
|
resetDatabase(): Promise<void>;
|
|
8109
8120
|
/**
|
package/dist/react/index.mjs
CHANGED
|
@@ -121,7 +121,7 @@ import {
|
|
|
121
121
|
updateVaultMemoryEmbeddingOp,
|
|
122
122
|
updateVaultMemoryOp,
|
|
123
123
|
useEncryption
|
|
124
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-SEZCFG24.mjs";
|
|
125
125
|
import {
|
|
126
126
|
PiiRedactor,
|
|
127
127
|
createStreamingDeAnonymizer,
|
|
@@ -6916,7 +6916,18 @@ For each durable fact, output:
|
|
|
6916
6916
|
- type: one of identity | preference | relationship | plan | ongoing_context | constraint | other
|
|
6917
6917
|
- confidence: 0.0-1.0; how sure you are this is durable AND true. Only include facts >= 0.7.
|
|
6918
6918
|
- sourceMessageIds: which message IDs from the conversation contained the evidence
|
|
6919
|
-
- entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "place" | "thing" | "concept" | "other" }. Optional
|
|
6919
|
+
- 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. Choose the MOST SPECIFIC kind:
|
|
6920
|
+
- person: a named individual ("Sara", "Dr. Lee")
|
|
6921
|
+
- organization: a company, team, school, or group ("Google", "the Warriors", "Stanford")
|
|
6922
|
+
- place: a geographic location or venue ("San Francisco", "Blue Bottle on Valencia")
|
|
6923
|
+
- event: a dated or nameable occurrence ("Chicago Marathon", "the Japan trip", "their wedding")
|
|
6924
|
+
- product: a named app, tool, brand, device, book, film, or other media title ("Linear", "iPhone", "Dune", "Ableton")
|
|
6925
|
+
- thing: a concrete physical object that isn't a branded product ("road bike", "sourdough starter")
|
|
6926
|
+
- concept: a topic, skill, field, language, or idea ("machine learning", "Spanish", "async communication")
|
|
6927
|
+
- other: a named entity that genuinely fits none of the above \u2014 use sparingly
|
|
6928
|
+
Prefer organization / product / event / place over the generic "thing"; fall back to "thing" or "other" only when no specific kind fits. Examples:
|
|
6929
|
+
- "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" }]
|
|
6930
|
+
- "running the Berlin Half in May and I track workouts in Whoop" \u2192 entities: [{ "name": "Berlin Half", "kind": "event" }, { "name": "Whoop", "kind": "product" }]
|
|
6920
6931
|
- 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:
|
|
6921
6932
|
- { "kind": "point", "start": "YYYY-MM-DD" } for a single date ("met Sara on March 14, 2026")
|
|
6922
6933
|
- { "kind": "range", "start": "YYYY-MM-DD", "end": "YYYY-MM-DD" } for a span ("Japan trip May 4\u201315, 2026")
|
|
@@ -12680,8 +12691,18 @@ function getMigrationReloadKey(prefix, walletAddress) {
|
|
|
12680
12691
|
}
|
|
12681
12692
|
var DatabaseManager = class {
|
|
12682
12693
|
constructor(options) {
|
|
12683
|
-
|
|
12684
|
-
|
|
12694
|
+
/**
|
|
12695
|
+
* WatermelonDB instances cached by their derived `dbName` (not by raw wallet
|
|
12696
|
+
* address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
|
|
12697
|
+
* that is requested again — including after a transient `undefined`/guest
|
|
12698
|
+
* excursion or an address that briefly arrives in a different form during
|
|
12699
|
+
* sign-up — reuses the SAME instance instead of being torn down and rebuilt.
|
|
12700
|
+
* The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
|
|
12701
|
+
* (client#4821). Instances are kept for the lifetime of the manager (typically
|
|
12702
|
+
* guest + one wallet); switching wallets keeps prior ones cached rather than
|
|
12703
|
+
* disposing an instance the app may still hold a reference to.
|
|
12704
|
+
*/
|
|
12705
|
+
this.databases = /* @__PURE__ */ new Map();
|
|
12685
12706
|
this.migrationInProgress = false;
|
|
12686
12707
|
this.dbNamePrefix = options.dbNamePrefix;
|
|
12687
12708
|
this.createAdapter = options.createAdapter;
|
|
@@ -12698,8 +12719,9 @@ var DatabaseManager = class {
|
|
|
12698
12719
|
/**
|
|
12699
12720
|
* Get or create a WatermelonDB Database instance for the given wallet.
|
|
12700
12721
|
*
|
|
12701
|
-
*
|
|
12702
|
-
*
|
|
12722
|
+
* Instances are cached per derived dbName and reused across calls (including
|
|
12723
|
+
* repeat/guest-interleaved requests for the same wallet); a new one is built
|
|
12724
|
+
* only for a dbName not yet seen. See the `databases` field for why.
|
|
12703
12725
|
*
|
|
12704
12726
|
* @param walletAddress - The wallet address to scope the database to.
|
|
12705
12727
|
* If undefined, uses a "guest" database.
|
|
@@ -12707,46 +12729,47 @@ var DatabaseManager = class {
|
|
|
12707
12729
|
* @throws If a destructive migration is in progress
|
|
12708
12730
|
*/
|
|
12709
12731
|
getDatabase(walletAddress) {
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12713
|
-
|
|
12714
|
-
to: walletAddress
|
|
12715
|
-
});
|
|
12716
|
-
this.database = null;
|
|
12717
|
-
}
|
|
12718
|
-
if (this.database) {
|
|
12719
|
-
return this.database;
|
|
12732
|
+
const dbName = this.getDbName(walletAddress);
|
|
12733
|
+
const cached = this.databases.get(dbName);
|
|
12734
|
+
if (cached) {
|
|
12735
|
+
return cached;
|
|
12720
12736
|
}
|
|
12721
12737
|
const needsMigration = this.handleSchemaMigration(walletAddress);
|
|
12722
12738
|
if (needsMigration) {
|
|
12723
12739
|
throw new Error("Database migration in progress - app will restart");
|
|
12724
12740
|
}
|
|
12725
|
-
this.currentWalletAddress = walletAddress;
|
|
12726
|
-
const dbName = this.getDbName(walletAddress);
|
|
12727
12741
|
this.logger.debug?.("Initializing database", {
|
|
12728
12742
|
component: "DatabaseManager",
|
|
12729
12743
|
dbName,
|
|
12730
12744
|
walletAddress
|
|
12731
12745
|
});
|
|
12732
12746
|
const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
|
|
12733
|
-
|
|
12747
|
+
const database = new Database({
|
|
12734
12748
|
adapter,
|
|
12735
12749
|
modelClasses: sdkModelClasses
|
|
12736
12750
|
});
|
|
12737
|
-
|
|
12751
|
+
this.databases.set(dbName, database);
|
|
12752
|
+
return database;
|
|
12738
12753
|
}
|
|
12739
12754
|
/**
|
|
12740
|
-
* Reset
|
|
12755
|
+
* Reset ALL cached databases (useful for logout or testing).
|
|
12741
12756
|
*/
|
|
12742
12757
|
async resetDatabase() {
|
|
12743
|
-
const
|
|
12744
|
-
|
|
12745
|
-
|
|
12746
|
-
await db.
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
|
|
12758
|
+
const errors = [];
|
|
12759
|
+
for (const [dbName, db] of [...this.databases.entries()]) {
|
|
12760
|
+
try {
|
|
12761
|
+
await db.write(async () => {
|
|
12762
|
+
await db.unsafeResetDatabase();
|
|
12763
|
+
});
|
|
12764
|
+
this.databases.delete(dbName);
|
|
12765
|
+
} catch (error) {
|
|
12766
|
+
errors.push({ dbName, error });
|
|
12767
|
+
}
|
|
12768
|
+
}
|
|
12769
|
+
if (errors.length > 0) {
|
|
12770
|
+
throw new Error(
|
|
12771
|
+
`Failed to reset ${errors.length} database(s): ${errors.map((e) => e.dbName).join(", ")}`
|
|
12772
|
+
);
|
|
12750
12773
|
}
|
|
12751
12774
|
}
|
|
12752
12775
|
/**
|
|
@@ -15782,7 +15782,16 @@ function makeSyntheticStoredConversation(opts, defaultTitle) {
|
|
|
15782
15782
|
var import_watermelondb2 = __toESM(require_watermelondb());
|
|
15783
15783
|
|
|
15784
15784
|
// src/lib/db/entities/types.ts
|
|
15785
|
-
var ENTITY_KINDS = [
|
|
15785
|
+
var ENTITY_KINDS = [
|
|
15786
|
+
"person",
|
|
15787
|
+
"organization",
|
|
15788
|
+
"place",
|
|
15789
|
+
"event",
|
|
15790
|
+
"product",
|
|
15791
|
+
"thing",
|
|
15792
|
+
"concept",
|
|
15793
|
+
"other"
|
|
15794
|
+
];
|
|
15786
15795
|
function normalizeEntityName(name) {
|
|
15787
15796
|
return name.trim().toLowerCase();
|
|
15788
15797
|
}
|
|
@@ -18838,7 +18847,7 @@ function createMemoryVaultSearchTool(vaultCtx, embeddingOptions, cache, searchOp
|
|
|
18838
18847
|
legacy.map((r) => ({ id: r.uniqueId, content: r.content, score: r.similarity }))
|
|
18839
18848
|
);
|
|
18840
18849
|
}
|
|
18841
|
-
const { recall: recall2 } = await import("./recall-
|
|
18850
|
+
const { recall: recall2 } = await import("./recall-24ZIA2VL.mjs");
|
|
18842
18851
|
const result = await recall2(
|
|
18843
18852
|
query,
|
|
18844
18853
|
{ vaultCtx, embeddingOptions, vaultCache: cache },
|
package/dist/server/index.cjs
CHANGED
|
@@ -16568,7 +16568,16 @@ var ENTITY_KINDS;
|
|
|
16568
16568
|
var init_types3 = __esm({
|
|
16569
16569
|
"src/lib/db/entities/types.ts"() {
|
|
16570
16570
|
"use strict";
|
|
16571
|
-
ENTITY_KINDS = [
|
|
16571
|
+
ENTITY_KINDS = [
|
|
16572
|
+
"person",
|
|
16573
|
+
"organization",
|
|
16574
|
+
"place",
|
|
16575
|
+
"event",
|
|
16576
|
+
"product",
|
|
16577
|
+
"thing",
|
|
16578
|
+
"concept",
|
|
16579
|
+
"other"
|
|
16580
|
+
];
|
|
16572
16581
|
}
|
|
16573
16582
|
});
|
|
16574
16583
|
|
|
@@ -22893,8 +22902,18 @@ function getMigrationReloadKey(prefix, walletAddress) {
|
|
|
22893
22902
|
}
|
|
22894
22903
|
var DatabaseManager = class {
|
|
22895
22904
|
constructor(options) {
|
|
22896
|
-
|
|
22897
|
-
|
|
22905
|
+
/**
|
|
22906
|
+
* WatermelonDB instances cached by their derived `dbName` (not by raw wallet
|
|
22907
|
+
* address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
|
|
22908
|
+
* that is requested again — including after a transient `undefined`/guest
|
|
22909
|
+
* excursion or an address that briefly arrives in a different form during
|
|
22910
|
+
* sign-up — reuses the SAME instance instead of being torn down and rebuilt.
|
|
22911
|
+
* The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
|
|
22912
|
+
* (client#4821). Instances are kept for the lifetime of the manager (typically
|
|
22913
|
+
* guest + one wallet); switching wallets keeps prior ones cached rather than
|
|
22914
|
+
* disposing an instance the app may still hold a reference to.
|
|
22915
|
+
*/
|
|
22916
|
+
this.databases = /* @__PURE__ */ new Map();
|
|
22898
22917
|
this.migrationInProgress = false;
|
|
22899
22918
|
this.dbNamePrefix = options.dbNamePrefix;
|
|
22900
22919
|
this.createAdapter = options.createAdapter;
|
|
@@ -22911,8 +22930,9 @@ var DatabaseManager = class {
|
|
|
22911
22930
|
/**
|
|
22912
22931
|
* Get or create a WatermelonDB Database instance for the given wallet.
|
|
22913
22932
|
*
|
|
22914
|
-
*
|
|
22915
|
-
*
|
|
22933
|
+
* Instances are cached per derived dbName and reused across calls (including
|
|
22934
|
+
* repeat/guest-interleaved requests for the same wallet); a new one is built
|
|
22935
|
+
* only for a dbName not yet seen. See the `databases` field for why.
|
|
22916
22936
|
*
|
|
22917
22937
|
* @param walletAddress - The wallet address to scope the database to.
|
|
22918
22938
|
* If undefined, uses a "guest" database.
|
|
@@ -22920,46 +22940,47 @@ var DatabaseManager = class {
|
|
|
22920
22940
|
* @throws If a destructive migration is in progress
|
|
22921
22941
|
*/
|
|
22922
22942
|
getDatabase(walletAddress) {
|
|
22923
|
-
|
|
22924
|
-
|
|
22925
|
-
|
|
22926
|
-
|
|
22927
|
-
to: walletAddress
|
|
22928
|
-
});
|
|
22929
|
-
this.database = null;
|
|
22930
|
-
}
|
|
22931
|
-
if (this.database) {
|
|
22932
|
-
return this.database;
|
|
22943
|
+
const dbName = this.getDbName(walletAddress);
|
|
22944
|
+
const cached = this.databases.get(dbName);
|
|
22945
|
+
if (cached) {
|
|
22946
|
+
return cached;
|
|
22933
22947
|
}
|
|
22934
22948
|
const needsMigration = this.handleSchemaMigration(walletAddress);
|
|
22935
22949
|
if (needsMigration) {
|
|
22936
22950
|
throw new Error("Database migration in progress - app will restart");
|
|
22937
22951
|
}
|
|
22938
|
-
this.currentWalletAddress = walletAddress;
|
|
22939
|
-
const dbName = this.getDbName(walletAddress);
|
|
22940
22952
|
this.logger.debug?.("Initializing database", {
|
|
22941
22953
|
component: "DatabaseManager",
|
|
22942
22954
|
dbName,
|
|
22943
22955
|
walletAddress
|
|
22944
22956
|
});
|
|
22945
22957
|
const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
|
|
22946
|
-
|
|
22958
|
+
const database = new import_watermelondb13.Database({
|
|
22947
22959
|
adapter,
|
|
22948
22960
|
modelClasses: sdkModelClasses
|
|
22949
22961
|
});
|
|
22950
|
-
|
|
22962
|
+
this.databases.set(dbName, database);
|
|
22963
|
+
return database;
|
|
22951
22964
|
}
|
|
22952
22965
|
/**
|
|
22953
|
-
* Reset
|
|
22966
|
+
* Reset ALL cached databases (useful for logout or testing).
|
|
22954
22967
|
*/
|
|
22955
22968
|
async resetDatabase() {
|
|
22956
|
-
const
|
|
22957
|
-
|
|
22958
|
-
|
|
22959
|
-
await db.
|
|
22960
|
-
|
|
22961
|
-
|
|
22962
|
-
|
|
22969
|
+
const errors = [];
|
|
22970
|
+
for (const [dbName, db] of [...this.databases.entries()]) {
|
|
22971
|
+
try {
|
|
22972
|
+
await db.write(async () => {
|
|
22973
|
+
await db.unsafeResetDatabase();
|
|
22974
|
+
});
|
|
22975
|
+
this.databases.delete(dbName);
|
|
22976
|
+
} catch (error) {
|
|
22977
|
+
errors.push({ dbName, error });
|
|
22978
|
+
}
|
|
22979
|
+
}
|
|
22980
|
+
if (errors.length > 0) {
|
|
22981
|
+
throw new Error(
|
|
22982
|
+
`Failed to reset ${errors.length} database(s): ${errors.map((e) => e.dbName).join(", ")}`
|
|
22983
|
+
);
|
|
22963
22984
|
}
|
|
22964
22985
|
}
|
|
22965
22986
|
/**
|
|
@@ -25802,7 +25823,18 @@ For each durable fact, output:
|
|
|
25802
25823
|
- type: one of identity | preference | relationship | plan | ongoing_context | constraint | other
|
|
25803
25824
|
- confidence: 0.0-1.0; how sure you are this is durable AND true. Only include facts >= 0.7.
|
|
25804
25825
|
- sourceMessageIds: which message IDs from the conversation contained the evidence
|
|
25805
|
-
- entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "place" | "thing" | "concept" | "other" }. Optional
|
|
25826
|
+
- 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. Choose the MOST SPECIFIC kind:
|
|
25827
|
+
- person: a named individual ("Sara", "Dr. Lee")
|
|
25828
|
+
- organization: a company, team, school, or group ("Google", "the Warriors", "Stanford")
|
|
25829
|
+
- place: a geographic location or venue ("San Francisco", "Blue Bottle on Valencia")
|
|
25830
|
+
- event: a dated or nameable occurrence ("Chicago Marathon", "the Japan trip", "their wedding")
|
|
25831
|
+
- product: a named app, tool, brand, device, book, film, or other media title ("Linear", "iPhone", "Dune", "Ableton")
|
|
25832
|
+
- thing: a concrete physical object that isn't a branded product ("road bike", "sourdough starter")
|
|
25833
|
+
- concept: a topic, skill, field, language, or idea ("machine learning", "Spanish", "async communication")
|
|
25834
|
+
- other: a named entity that genuinely fits none of the above \u2014 use sparingly
|
|
25835
|
+
Prefer organization / product / event / place over the generic "thing"; fall back to "thing" or "other" only when no specific kind fits. Examples:
|
|
25836
|
+
- "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" }]
|
|
25837
|
+
- "running the Berlin Half in May and I track workouts in Whoop" \u2192 entities: [{ "name": "Berlin Half", "kind": "event" }, { "name": "Whoop", "kind": "product" }]
|
|
25806
25838
|
- 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:
|
|
25807
25839
|
- { "kind": "point", "start": "YYYY-MM-DD" } for a single date ("met Sara on March 14, 2026")
|
|
25808
25840
|
- { "kind": "range", "start": "YYYY-MM-DD", "end": "YYYY-MM-DD" } for a span ("Japan trip May 4\u201315, 2026")
|
package/dist/server/index.d.mts
CHANGED
|
@@ -248,8 +248,18 @@ interface DatabaseManagerOptions {
|
|
|
248
248
|
* ```
|
|
249
249
|
*/
|
|
250
250
|
declare class DatabaseManager {
|
|
251
|
-
|
|
252
|
-
|
|
251
|
+
/**
|
|
252
|
+
* WatermelonDB instances cached by their derived `dbName` (not by raw wallet
|
|
253
|
+
* address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
|
|
254
|
+
* that is requested again — including after a transient `undefined`/guest
|
|
255
|
+
* excursion or an address that briefly arrives in a different form during
|
|
256
|
+
* sign-up — reuses the SAME instance instead of being torn down and rebuilt.
|
|
257
|
+
* The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
|
|
258
|
+
* (client#4821). Instances are kept for the lifetime of the manager (typically
|
|
259
|
+
* guest + one wallet); switching wallets keeps prior ones cached rather than
|
|
260
|
+
* disposing an instance the app may still hold a reference to.
|
|
261
|
+
*/
|
|
262
|
+
private readonly databases;
|
|
253
263
|
private migrationInProgress;
|
|
254
264
|
private readonly dbNamePrefix;
|
|
255
265
|
private readonly createAdapter;
|
|
@@ -264,8 +274,9 @@ declare class DatabaseManager {
|
|
|
264
274
|
/**
|
|
265
275
|
* Get or create a WatermelonDB Database instance for the given wallet.
|
|
266
276
|
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
277
|
+
* Instances are cached per derived dbName and reused across calls (including
|
|
278
|
+
* repeat/guest-interleaved requests for the same wallet); a new one is built
|
|
279
|
+
* only for a dbName not yet seen. See the `databases` field for why.
|
|
269
280
|
*
|
|
270
281
|
* @param walletAddress - The wallet address to scope the database to.
|
|
271
282
|
* If undefined, uses a "guest" database.
|
|
@@ -274,7 +285,7 @@ declare class DatabaseManager {
|
|
|
274
285
|
*/
|
|
275
286
|
getDatabase(walletAddress?: string): Database;
|
|
276
287
|
/**
|
|
277
|
-
* Reset
|
|
288
|
+
* Reset ALL cached databases (useful for logout or testing).
|
|
278
289
|
*/
|
|
279
290
|
resetDatabase(): Promise<void>;
|
|
280
291
|
/**
|
|
@@ -4132,7 +4143,7 @@ declare class MemoryEntity extends Model$1 {
|
|
|
4132
4143
|
* can't drift apart.
|
|
4133
4144
|
* @public
|
|
4134
4145
|
*/
|
|
4135
|
-
declare const ENTITY_KINDS: readonly ["person", "place", "thing", "concept", "other"];
|
|
4146
|
+
declare const ENTITY_KINDS: readonly ["person", "organization", "place", "event", "product", "thing", "concept", "other"];
|
|
4136
4147
|
/** @public */
|
|
4137
4148
|
type EntityKind = (typeof ENTITY_KINDS)[number];
|
|
4138
4149
|
|
package/dist/server/index.d.ts
CHANGED
|
@@ -248,8 +248,18 @@ interface DatabaseManagerOptions {
|
|
|
248
248
|
* ```
|
|
249
249
|
*/
|
|
250
250
|
declare class DatabaseManager {
|
|
251
|
-
|
|
252
|
-
|
|
251
|
+
/**
|
|
252
|
+
* WatermelonDB instances cached by their derived `dbName` (not by raw wallet
|
|
253
|
+
* address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
|
|
254
|
+
* that is requested again — including after a transient `undefined`/guest
|
|
255
|
+
* excursion or an address that briefly arrives in a different form during
|
|
256
|
+
* sign-up — reuses the SAME instance instead of being torn down and rebuilt.
|
|
257
|
+
* The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
|
|
258
|
+
* (client#4821). Instances are kept for the lifetime of the manager (typically
|
|
259
|
+
* guest + one wallet); switching wallets keeps prior ones cached rather than
|
|
260
|
+
* disposing an instance the app may still hold a reference to.
|
|
261
|
+
*/
|
|
262
|
+
private readonly databases;
|
|
253
263
|
private migrationInProgress;
|
|
254
264
|
private readonly dbNamePrefix;
|
|
255
265
|
private readonly createAdapter;
|
|
@@ -264,8 +274,9 @@ declare class DatabaseManager {
|
|
|
264
274
|
/**
|
|
265
275
|
* Get or create a WatermelonDB Database instance for the given wallet.
|
|
266
276
|
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
277
|
+
* Instances are cached per derived dbName and reused across calls (including
|
|
278
|
+
* repeat/guest-interleaved requests for the same wallet); a new one is built
|
|
279
|
+
* only for a dbName not yet seen. See the `databases` field for why.
|
|
269
280
|
*
|
|
270
281
|
* @param walletAddress - The wallet address to scope the database to.
|
|
271
282
|
* If undefined, uses a "guest" database.
|
|
@@ -274,7 +285,7 @@ declare class DatabaseManager {
|
|
|
274
285
|
*/
|
|
275
286
|
getDatabase(walletAddress?: string): Database;
|
|
276
287
|
/**
|
|
277
|
-
* Reset
|
|
288
|
+
* Reset ALL cached databases (useful for logout or testing).
|
|
278
289
|
*/
|
|
279
290
|
resetDatabase(): Promise<void>;
|
|
280
291
|
/**
|
|
@@ -4132,7 +4143,7 @@ declare class MemoryEntity extends Model$1 {
|
|
|
4132
4143
|
* can't drift apart.
|
|
4133
4144
|
* @public
|
|
4134
4145
|
*/
|
|
4135
|
-
declare const ENTITY_KINDS: readonly ["person", "place", "thing", "concept", "other"];
|
|
4146
|
+
declare const ENTITY_KINDS: readonly ["person", "organization", "place", "event", "product", "thing", "concept", "other"];
|
|
4136
4147
|
/** @public */
|
|
4137
4148
|
type EntityKind = (typeof ENTITY_KINDS)[number];
|
|
4138
4149
|
|
package/dist/server/index.mjs
CHANGED
|
@@ -95,7 +95,7 @@ import {
|
|
|
95
95
|
updateVaultMemoryEmbeddingOp,
|
|
96
96
|
updateVaultMemoryOp,
|
|
97
97
|
upsertMessageOp
|
|
98
|
-
} from "./chunk-
|
|
98
|
+
} from "./chunk-Z7CJGOTG.mjs";
|
|
99
99
|
import {
|
|
100
100
|
createStreamingDeAnonymizer,
|
|
101
101
|
resolvePiiRedactor
|
|
@@ -2000,8 +2000,18 @@ function getMigrationReloadKey(prefix, walletAddress) {
|
|
|
2000
2000
|
}
|
|
2001
2001
|
var DatabaseManager = class {
|
|
2002
2002
|
constructor(options) {
|
|
2003
|
-
|
|
2004
|
-
|
|
2003
|
+
/**
|
|
2004
|
+
* WatermelonDB instances cached by their derived `dbName` (not by raw wallet
|
|
2005
|
+
* address). Caching per dbName makes {@link getDatabase} idempotent: a wallet
|
|
2006
|
+
* that is requested again — including after a transient `undefined`/guest
|
|
2007
|
+
* excursion or an address that briefly arrives in a different form during
|
|
2008
|
+
* sign-up — reuses the SAME instance instead of being torn down and rebuilt.
|
|
2009
|
+
* The rebuild was what left the web OPFS adapter disposed/orphaned mid-session
|
|
2010
|
+
* (client#4821). Instances are kept for the lifetime of the manager (typically
|
|
2011
|
+
* guest + one wallet); switching wallets keeps prior ones cached rather than
|
|
2012
|
+
* disposing an instance the app may still hold a reference to.
|
|
2013
|
+
*/
|
|
2014
|
+
this.databases = /* @__PURE__ */ new Map();
|
|
2005
2015
|
this.migrationInProgress = false;
|
|
2006
2016
|
this.dbNamePrefix = options.dbNamePrefix;
|
|
2007
2017
|
this.createAdapter = options.createAdapter;
|
|
@@ -2018,8 +2028,9 @@ var DatabaseManager = class {
|
|
|
2018
2028
|
/**
|
|
2019
2029
|
* Get or create a WatermelonDB Database instance for the given wallet.
|
|
2020
2030
|
*
|
|
2021
|
-
*
|
|
2022
|
-
*
|
|
2031
|
+
* Instances are cached per derived dbName and reused across calls (including
|
|
2032
|
+
* repeat/guest-interleaved requests for the same wallet); a new one is built
|
|
2033
|
+
* only for a dbName not yet seen. See the `databases` field for why.
|
|
2023
2034
|
*
|
|
2024
2035
|
* @param walletAddress - The wallet address to scope the database to.
|
|
2025
2036
|
* If undefined, uses a "guest" database.
|
|
@@ -2027,46 +2038,47 @@ var DatabaseManager = class {
|
|
|
2027
2038
|
* @throws If a destructive migration is in progress
|
|
2028
2039
|
*/
|
|
2029
2040
|
getDatabase(walletAddress) {
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
to: walletAddress
|
|
2035
|
-
});
|
|
2036
|
-
this.database = null;
|
|
2037
|
-
}
|
|
2038
|
-
if (this.database) {
|
|
2039
|
-
return this.database;
|
|
2041
|
+
const dbName = this.getDbName(walletAddress);
|
|
2042
|
+
const cached = this.databases.get(dbName);
|
|
2043
|
+
if (cached) {
|
|
2044
|
+
return cached;
|
|
2040
2045
|
}
|
|
2041
2046
|
const needsMigration = this.handleSchemaMigration(walletAddress);
|
|
2042
2047
|
if (needsMigration) {
|
|
2043
2048
|
throw new Error("Database migration in progress - app will restart");
|
|
2044
2049
|
}
|
|
2045
|
-
this.currentWalletAddress = walletAddress;
|
|
2046
|
-
const dbName = this.getDbName(walletAddress);
|
|
2047
2050
|
this.logger.debug?.("Initializing database", {
|
|
2048
2051
|
component: "DatabaseManager",
|
|
2049
2052
|
dbName,
|
|
2050
2053
|
walletAddress
|
|
2051
2054
|
});
|
|
2052
2055
|
const adapter = this.createAdapter(dbName, sdkSchema, sdkMigrations);
|
|
2053
|
-
|
|
2056
|
+
const database = new import_watermelondb13.Database({
|
|
2054
2057
|
adapter,
|
|
2055
2058
|
modelClasses: sdkModelClasses
|
|
2056
2059
|
});
|
|
2057
|
-
|
|
2060
|
+
this.databases.set(dbName, database);
|
|
2061
|
+
return database;
|
|
2058
2062
|
}
|
|
2059
2063
|
/**
|
|
2060
|
-
* Reset
|
|
2064
|
+
* Reset ALL cached databases (useful for logout or testing).
|
|
2061
2065
|
*/
|
|
2062
2066
|
async resetDatabase() {
|
|
2063
|
-
const
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
await db.
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2067
|
+
const errors = [];
|
|
2068
|
+
for (const [dbName, db] of [...this.databases.entries()]) {
|
|
2069
|
+
try {
|
|
2070
|
+
await db.write(async () => {
|
|
2071
|
+
await db.unsafeResetDatabase();
|
|
2072
|
+
});
|
|
2073
|
+
this.databases.delete(dbName);
|
|
2074
|
+
} catch (error) {
|
|
2075
|
+
errors.push({ dbName, error });
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
if (errors.length > 0) {
|
|
2079
|
+
throw new Error(
|
|
2080
|
+
`Failed to reset ${errors.length} database(s): ${errors.map((e) => e.dbName).join(", ")}`
|
|
2081
|
+
);
|
|
2070
2082
|
}
|
|
2071
2083
|
}
|
|
2072
2084
|
/**
|
|
@@ -4870,7 +4882,18 @@ For each durable fact, output:
|
|
|
4870
4882
|
- type: one of identity | preference | relationship | plan | ongoing_context | constraint | other
|
|
4871
4883
|
- confidence: 0.0-1.0; how sure you are this is durable AND true. Only include facts >= 0.7.
|
|
4872
4884
|
- sourceMessageIds: which message IDs from the conversation contained the evidence
|
|
4873
|
-
- entities: named entities mentioned, each as an object { "name": string, "kind": one of "person" | "place" | "thing" | "concept" | "other" }. Optional
|
|
4885
|
+
- 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. Choose the MOST SPECIFIC kind:
|
|
4886
|
+
- person: a named individual ("Sara", "Dr. Lee")
|
|
4887
|
+
- organization: a company, team, school, or group ("Google", "the Warriors", "Stanford")
|
|
4888
|
+
- place: a geographic location or venue ("San Francisco", "Blue Bottle on Valencia")
|
|
4889
|
+
- event: a dated or nameable occurrence ("Chicago Marathon", "the Japan trip", "their wedding")
|
|
4890
|
+
- product: a named app, tool, brand, device, book, film, or other media title ("Linear", "iPhone", "Dune", "Ableton")
|
|
4891
|
+
- thing: a concrete physical object that isn't a branded product ("road bike", "sourdough starter")
|
|
4892
|
+
- concept: a topic, skill, field, language, or idea ("machine learning", "Spanish", "async communication")
|
|
4893
|
+
- other: a named entity that genuinely fits none of the above \u2014 use sparingly
|
|
4894
|
+
Prefer organization / product / event / place over the generic "thing"; fall back to "thing" or "other" only when no specific kind fits. Examples:
|
|
4895
|
+
- "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" }]
|
|
4896
|
+
- "running the Berlin Half in May and I track workouts in Whoop" \u2192 entities: [{ "name": "Berlin Half", "kind": "event" }, { "name": "Whoop", "kind": "product" }]
|
|
4874
4897
|
- 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:
|
|
4875
4898
|
- { "kind": "point", "start": "YYYY-MM-DD" } for a single date ("met Sara on March 14, 2026")
|
|
4876
4899
|
- { "kind": "range", "start": "YYYY-MM-DD", "end": "YYYY-MM-DD" } for a span ("Japan trip May 4\u201315, 2026")
|