@plur-ai/core 0.9.5 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +10 -0
- package/dist/index.js +62 -3
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -2252,6 +2252,16 @@ declare class Plur {
|
|
|
2252
2252
|
* freshness and closes the race. See issue #25.
|
|
2253
2253
|
*/
|
|
2254
2254
|
private _writeEngrams;
|
|
2255
|
+
/**
|
|
2256
|
+
* Resolve a remote store for a write scope. Returns the RemoteStore driver
|
|
2257
|
+
* if the engram's scope matches a registered remote entry, else null.
|
|
2258
|
+
*
|
|
2259
|
+
* Match rule (pilot scope): exact-match `entry.scope === engramScope`. We
|
|
2260
|
+
* intentionally don't do prefix-match yet — agents that want to write to a
|
|
2261
|
+
* narrower scope than they registered must explicitly register the narrower
|
|
2262
|
+
* scope. Keeps routing predictable and prevents accidental cross-team writes.
|
|
2263
|
+
*/
|
|
2264
|
+
private _resolveRemoteStoreForScope;
|
|
2255
2265
|
/** Find which store owns an engram by ID. For namespaced IDs, strips prefix to find in store. */
|
|
2256
2266
|
private _findEngramStore;
|
|
2257
2267
|
/** Content hash fast-path dedup. */
|
package/dist/index.js
CHANGED
|
@@ -283,10 +283,31 @@ var PlurConfigSchema = z.object({
|
|
|
283
283
|
// src/config.ts
|
|
284
284
|
function loadConfig(configPath) {
|
|
285
285
|
if (!existsSync3(configPath)) return PlurConfigSchema.parse({});
|
|
286
|
+
let raw;
|
|
286
287
|
try {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
288
|
+
raw = yaml.load(readFileSync(configPath, "utf8")) ?? {};
|
|
289
|
+
} catch (err) {
|
|
290
|
+
logger.warning(`[plur:config] cannot parse YAML at ${configPath}: ${err.message} \u2014 falling back to defaults`);
|
|
291
|
+
return PlurConfigSchema.parse({});
|
|
292
|
+
}
|
|
293
|
+
if (Array.isArray(raw.stores)) {
|
|
294
|
+
const validStores = [];
|
|
295
|
+
for (let i = 0; i < raw.stores.length; i++) {
|
|
296
|
+
const entry = raw.stores[i];
|
|
297
|
+
const parsed = StoreEntrySchema.safeParse(entry);
|
|
298
|
+
if (parsed.success) {
|
|
299
|
+
validStores.push(entry);
|
|
300
|
+
} else {
|
|
301
|
+
const label = entry?.scope ?? entry?.url ?? entry?.path ?? `index ${i}`;
|
|
302
|
+
logger.warning(`[plur:config] dropping invalid stores[${i}] (${label}) from ${configPath}: ${parsed.error.issues.map((it) => it.message).join("; ")}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
raw.stores = validStores;
|
|
306
|
+
}
|
|
307
|
+
try {
|
|
308
|
+
return PlurConfigSchema.parse(raw);
|
|
309
|
+
} catch (err) {
|
|
310
|
+
logger.warning(`[plur:config] top-level config invalid at ${configPath}: ${err.message} \u2014 falling back to defaults`);
|
|
290
311
|
return PlurConfigSchema.parse({});
|
|
291
312
|
}
|
|
292
313
|
}
|
|
@@ -3442,6 +3463,31 @@ var Plur = class {
|
|
|
3442
3463
|
saveEngrams(path3, engrams);
|
|
3443
3464
|
this._engramCache.delete(path3);
|
|
3444
3465
|
}
|
|
3466
|
+
/**
|
|
3467
|
+
* Resolve a remote store for a write scope. Returns the RemoteStore driver
|
|
3468
|
+
* if the engram's scope matches a registered remote entry, else null.
|
|
3469
|
+
*
|
|
3470
|
+
* Match rule (pilot scope): exact-match `entry.scope === engramScope`. We
|
|
3471
|
+
* intentionally don't do prefix-match yet — agents that want to write to a
|
|
3472
|
+
* narrower scope than they registered must explicitly register the narrower
|
|
3473
|
+
* scope. Keeps routing predictable and prevents accidental cross-team writes.
|
|
3474
|
+
*/
|
|
3475
|
+
_resolveRemoteStoreForScope(scope) {
|
|
3476
|
+
const stores = this.config.stores ?? [];
|
|
3477
|
+
for (const entry of stores) {
|
|
3478
|
+
if (!entry.url) continue;
|
|
3479
|
+
if (entry.readonly === true) continue;
|
|
3480
|
+
if (entry.scope !== scope) continue;
|
|
3481
|
+
const key = `${entry.url}::${entry.scope}`;
|
|
3482
|
+
let driver = this._remoteStores.get(key);
|
|
3483
|
+
if (!driver) {
|
|
3484
|
+
driver = new RemoteStore(entry.url, entry.token ?? "", entry.scope);
|
|
3485
|
+
this._remoteStores.set(key, driver);
|
|
3486
|
+
}
|
|
3487
|
+
return driver;
|
|
3488
|
+
}
|
|
3489
|
+
return null;
|
|
3490
|
+
}
|
|
3445
3491
|
/** Find which store owns an engram by ID. For namespaced IDs, strips prefix to find in store. */
|
|
3446
3492
|
_findEngramStore(id) {
|
|
3447
3493
|
const primaryEngrams = this._loadCached(this.paths.engrams);
|
|
@@ -3572,6 +3618,19 @@ var Plur = class {
|
|
|
3572
3618
|
} : void 0,
|
|
3573
3619
|
pinned: context?.pinned === true ? true : void 0
|
|
3574
3620
|
};
|
|
3621
|
+
const remoteDriver = this._resolveRemoteStoreForScope(scope);
|
|
3622
|
+
if (remoteDriver) {
|
|
3623
|
+
void remoteDriver.append(engram).catch((err) => {
|
|
3624
|
+
logger.error(`[plur:learn] remote append failed for ${engram.id} (scope=${scope}): ${err.message}`);
|
|
3625
|
+
});
|
|
3626
|
+
appendHistory(this.paths.root, {
|
|
3627
|
+
event: "engram_created",
|
|
3628
|
+
engram_id: engram.id,
|
|
3629
|
+
timestamp: now,
|
|
3630
|
+
data: { type: engram.type, scope: engram.scope, source: engram.source, routed_to: "remote" }
|
|
3631
|
+
});
|
|
3632
|
+
return engram;
|
|
3633
|
+
}
|
|
3575
3634
|
engrams.push(engram);
|
|
3576
3635
|
this._writeEngrams(this.paths.engrams, engrams);
|
|
3577
3636
|
this._syncIndex();
|