@sanctuary-framework/mcp-server 1.2.5 → 1.2.6
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/cli.cjs +864 -35
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +864 -35
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +847 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +239 -3
- package/dist/index.d.ts +239 -3
- package/dist/index.js +847 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -17211,6 +17211,27 @@ async function handleApprovalInboxRoute(deps, req, res) {
|
|
|
17211
17211
|
await handleStream2(deps, res);
|
|
17212
17212
|
return true;
|
|
17213
17213
|
}
|
|
17214
|
+
if (method === "GET" && path === `${APPROVAL_INBOX_API_PREFIX}/history`) {
|
|
17215
|
+
const limit = parseLimit2(
|
|
17216
|
+
url.searchParams.get("limit"),
|
|
17217
|
+
APPROVAL_INBOX_DEFAULT_LIMIT,
|
|
17218
|
+
APPROVAL_INBOX_MAX_LIMIT
|
|
17219
|
+
);
|
|
17220
|
+
const statusRaw = url.searchParams.get("status");
|
|
17221
|
+
const sinceTs = url.searchParams.get("since") ?? void 0;
|
|
17222
|
+
const operatorId = deps.operatorId ?? APPROVAL_INBOX_OPERATOR_DEFAULT;
|
|
17223
|
+
const filterStatus = statusRaw && isStatusFilter(statusRaw) && statusRaw !== "pending" ? statusRaw : void 0;
|
|
17224
|
+
const entries = await deps.aggregator.getHistory(
|
|
17225
|
+
{
|
|
17226
|
+
limit,
|
|
17227
|
+
...filterStatus !== void 0 ? { status: filterStatus } : {},
|
|
17228
|
+
...sinceTs !== void 0 ? { sinceTs } : {}
|
|
17229
|
+
},
|
|
17230
|
+
operatorId
|
|
17231
|
+
);
|
|
17232
|
+
writeJSON4(res, 200, { ok: true, data: { entries } });
|
|
17233
|
+
return true;
|
|
17234
|
+
}
|
|
17214
17235
|
if (method === "GET" && path === APPROVAL_INBOX_API_PREFIX) {
|
|
17215
17236
|
const limit = parseLimit2(
|
|
17216
17237
|
url.searchParams.get("limit"),
|
|
@@ -17233,11 +17254,39 @@ async function handleApprovalInboxRoute(deps, req, res) {
|
|
|
17233
17254
|
writeJSON4(res, 404, { ok: false, error: "not_found", path });
|
|
17234
17255
|
return true;
|
|
17235
17256
|
}
|
|
17236
|
-
if (method === "GET" && entryMatch.action ===
|
|
17237
|
-
const
|
|
17238
|
-
|
|
17239
|
-
(
|
|
17257
|
+
if (method === "GET" && entryMatch.action === "audit-trail") {
|
|
17258
|
+
const entry = await deps.aggregator.getEntry(entryMatch.aggregatorId);
|
|
17259
|
+
if (!entry) {
|
|
17260
|
+
writeJSON4(res, 404, { ok: false, error: "not_found" });
|
|
17261
|
+
return true;
|
|
17262
|
+
}
|
|
17263
|
+
const operatorId = deps.operatorId ?? APPROVAL_INBOX_OPERATOR_DEFAULT;
|
|
17264
|
+
const trail = await deps.aggregator.getAuditTrail(
|
|
17265
|
+
entryMatch.aggregatorId,
|
|
17266
|
+
operatorId
|
|
17240
17267
|
);
|
|
17268
|
+
writeJSON4(res, 200, { ok: true, data: { entry, audit_trail: trail } });
|
|
17269
|
+
return true;
|
|
17270
|
+
}
|
|
17271
|
+
if (method === "GET" && entryMatch.action === "payload") {
|
|
17272
|
+
const entry = await deps.aggregator.getEntry(entryMatch.aggregatorId);
|
|
17273
|
+
if (!entry) {
|
|
17274
|
+
writeJSON4(res, 404, { ok: false, error: "not_found" });
|
|
17275
|
+
return true;
|
|
17276
|
+
}
|
|
17277
|
+
const operatorId = deps.operatorId ?? APPROVAL_INBOX_OPERATOR_DEFAULT;
|
|
17278
|
+
const payload = await deps.aggregator.getFullPayloadWithAudit(
|
|
17279
|
+
entryMatch.aggregatorId,
|
|
17280
|
+
operatorId
|
|
17281
|
+
);
|
|
17282
|
+
writeJSON4(res, 200, {
|
|
17283
|
+
ok: true,
|
|
17284
|
+
data: { entry, request_payload: payload }
|
|
17285
|
+
});
|
|
17286
|
+
return true;
|
|
17287
|
+
}
|
|
17288
|
+
if (method === "GET" && entryMatch.action === null) {
|
|
17289
|
+
const entry = await deps.aggregator.getEntry(entryMatch.aggregatorId);
|
|
17241
17290
|
if (!entry) {
|
|
17242
17291
|
writeJSON4(res, 404, { ok: false, error: "not_found" });
|
|
17243
17292
|
return true;
|
|
@@ -20271,7 +20320,10 @@ var init_approval_aggregator = __esm({
|
|
|
20271
20320
|
APPROVAL_AGGREGATOR_AUDIT_OPS = {
|
|
20272
20321
|
AGGREGATED: "cross_harness_approval_aggregated",
|
|
20273
20322
|
RESOLVED: "cross_harness_approval_resolved",
|
|
20274
|
-
DEDUPED: "cross_harness_approval_deduped"
|
|
20323
|
+
DEDUPED: "cross_harness_approval_deduped",
|
|
20324
|
+
PAYLOAD_DECRYPTED: "cross_harness_approval_payload_decrypted",
|
|
20325
|
+
AUDIT_TRAIL_VIEWED: "cross_harness_approval_audit_trail_viewed",
|
|
20326
|
+
REPLAYED: "cross_harness_approval_replayed"
|
|
20275
20327
|
};
|
|
20276
20328
|
DEFAULT_PENDING_TTL_MS = 5 * 60 * 1e3;
|
|
20277
20329
|
DEFAULT_MAX_LIST_LIMIT = 200;
|
|
@@ -20287,6 +20339,8 @@ var init_approval_aggregator = __esm({
|
|
|
20287
20339
|
now;
|
|
20288
20340
|
resolveSourceContext;
|
|
20289
20341
|
resolveHubInboxItemId;
|
|
20342
|
+
payloadStore;
|
|
20343
|
+
resolveEnforcementChain;
|
|
20290
20344
|
/** Cached entries by `aggregator_id`. */
|
|
20291
20345
|
entries = /* @__PURE__ */ new Map();
|
|
20292
20346
|
/** Dedup index: `${harness}|${agent}|${audit_id}` -> aggregator_id. */
|
|
@@ -20316,6 +20370,14 @@ var init_approval_aggregator = __esm({
|
|
|
20316
20370
|
source_agent_id: this.fortressId
|
|
20317
20371
|
}));
|
|
20318
20372
|
this.resolveHubInboxItemId = deps.resolveHubInboxItemId ?? ((_event) => void 0);
|
|
20373
|
+
this.payloadStore = deps.payloadStore ?? null;
|
|
20374
|
+
this.resolveEnforcementChain = deps.resolveEnforcementChain ?? ((event) => [
|
|
20375
|
+
{
|
|
20376
|
+
layer: "l2",
|
|
20377
|
+
event: `approval_required:${event.operation}`,
|
|
20378
|
+
timestamp: event.request_timestamp
|
|
20379
|
+
}
|
|
20380
|
+
]);
|
|
20319
20381
|
}
|
|
20320
20382
|
/**
|
|
20321
20383
|
* Subscribe an event listener. Returns an unsubscribe fn. SSE handlers
|
|
@@ -20366,13 +20428,152 @@ var init_approval_aggregator = __esm({
|
|
|
20366
20428
|
}
|
|
20367
20429
|
/**
|
|
20368
20430
|
* Return the original (unhashed) request payload for the entry. Returns
|
|
20369
|
-
* `null` when the entry is unknown
|
|
20370
|
-
*
|
|
20431
|
+
* `null` when the entry is unknown. When the in-memory payload map has
|
|
20432
|
+
* been evicted (e.g. after a server restart) and a `payloadStore` was
|
|
20433
|
+
* provided, the at-rest bundle is decrypted and the in-memory map is
|
|
20434
|
+
* refilled. Audit emission lives on the `*WithAudit` variant; this base
|
|
20435
|
+
* accessor is silent so internal callers can read without polluting the
|
|
20436
|
+
* audit trail.
|
|
20371
20437
|
*/
|
|
20372
20438
|
async getFullPayload(aggregatorId) {
|
|
20373
20439
|
await this.hydrate();
|
|
20374
20440
|
if (!this.entries.has(aggregatorId)) return null;
|
|
20375
|
-
|
|
20441
|
+
const cached = this.fullPayloads.get(aggregatorId);
|
|
20442
|
+
if (cached !== void 0) return cached;
|
|
20443
|
+
if (this.payloadStore) {
|
|
20444
|
+
try {
|
|
20445
|
+
const restored = await this.payloadStore.loadPayload(aggregatorId);
|
|
20446
|
+
if (restored !== null) {
|
|
20447
|
+
this.fullPayloads.set(aggregatorId, restored);
|
|
20448
|
+
return restored;
|
|
20449
|
+
}
|
|
20450
|
+
} catch {
|
|
20451
|
+
}
|
|
20452
|
+
}
|
|
20453
|
+
return null;
|
|
20454
|
+
}
|
|
20455
|
+
/**
|
|
20456
|
+
* Return the entry record for the given id, or null when unknown.
|
|
20457
|
+
* Idempotent. v1.3 Upsilon-3.
|
|
20458
|
+
*/
|
|
20459
|
+
async getEntry(aggregatorId) {
|
|
20460
|
+
await this.hydrate();
|
|
20461
|
+
return this.entries.get(aggregatorId) ?? null;
|
|
20462
|
+
}
|
|
20463
|
+
/**
|
|
20464
|
+
* Audited variant of `getFullPayload`. Emits the
|
|
20465
|
+
* `cross_harness_approval_payload_decrypted` audit event before
|
|
20466
|
+
* returning. Used by the operator-facing /payload replay route.
|
|
20467
|
+
* v1.3 Upsilon-3.
|
|
20468
|
+
*/
|
|
20469
|
+
async getFullPayloadWithAudit(aggregatorId, operatorId) {
|
|
20470
|
+
const payload = await this.getFullPayload(aggregatorId);
|
|
20471
|
+
if (payload === null) return null;
|
|
20472
|
+
const entry = this.entries.get(aggregatorId);
|
|
20473
|
+
this.auditLog.append(
|
|
20474
|
+
"l2",
|
|
20475
|
+
APPROVAL_AGGREGATOR_AUDIT_OPS.PAYLOAD_DECRYPTED,
|
|
20476
|
+
operatorId,
|
|
20477
|
+
{
|
|
20478
|
+
aggregator_id: aggregatorId,
|
|
20479
|
+
...entry ? {
|
|
20480
|
+
source_harness: entry.source_harness,
|
|
20481
|
+
source_agent_id: entry.source_agent_id,
|
|
20482
|
+
entry_status: entry.status
|
|
20483
|
+
} : {}
|
|
20484
|
+
}
|
|
20485
|
+
);
|
|
20486
|
+
return payload;
|
|
20487
|
+
}
|
|
20488
|
+
/**
|
|
20489
|
+
* Return the audit-log entries that led to and surround this approval.
|
|
20490
|
+
* Best-effort matching: aggregator-side emissions (AGGREGATED, RESOLVED,
|
|
20491
|
+
* DEDUPED, replay events) all carry `details.aggregator_id` and link
|
|
20492
|
+
* directly. Gate-side emissions (`gate_*:operation`) do not carry the
|
|
20493
|
+
* aggregator id at v1.3, so they are matched via timestamp window
|
|
20494
|
+
* (entry.created_at to entry.resolved_at + 1s, or expires_at + 1s while
|
|
20495
|
+
* pending) and operation suffix. Emits AUDIT_TRAIL_VIEWED on call.
|
|
20496
|
+
* v1.3 Upsilon-3.
|
|
20497
|
+
*/
|
|
20498
|
+
async getAuditTrail(aggregatorId, operatorId) {
|
|
20499
|
+
await this.hydrate();
|
|
20500
|
+
const entry = this.entries.get(aggregatorId);
|
|
20501
|
+
if (!entry) {
|
|
20502
|
+
return [];
|
|
20503
|
+
}
|
|
20504
|
+
const sinceMs = Date.parse(entry.created_at) - 1e3;
|
|
20505
|
+
const sinceIso = new Date(sinceMs).toISOString();
|
|
20506
|
+
const queried = await this.auditLog.query({ since: sinceIso, limit: 1e3 });
|
|
20507
|
+
const operationPart = entry.policy_rule_id.includes(":") ? entry.policy_rule_id.slice(entry.policy_rule_id.indexOf(":") + 1) : entry.policy_rule_id;
|
|
20508
|
+
const lifetimeStart = sinceMs;
|
|
20509
|
+
const lifetimeEnd = entry.resolved_at ? Date.parse(entry.resolved_at) + 1e3 : Date.parse(entry.expires_at) + 1e3;
|
|
20510
|
+
const matches = [];
|
|
20511
|
+
for (const audit of queried.entries) {
|
|
20512
|
+
const detailsId = audit.details !== void 0 ? audit.details["aggregator_id"] : void 0;
|
|
20513
|
+
if (detailsId === aggregatorId) {
|
|
20514
|
+
matches.push(audit);
|
|
20515
|
+
continue;
|
|
20516
|
+
}
|
|
20517
|
+
const auditMs = Date.parse(audit.timestamp);
|
|
20518
|
+
if (auditMs < lifetimeStart || auditMs > lifetimeEnd) continue;
|
|
20519
|
+
if (audit.operation.endsWith(`:${operationPart}`)) {
|
|
20520
|
+
matches.push(audit);
|
|
20521
|
+
}
|
|
20522
|
+
}
|
|
20523
|
+
matches.sort(
|
|
20524
|
+
(a, b) => a.timestamp < b.timestamp ? -1 : a.timestamp > b.timestamp ? 1 : 0
|
|
20525
|
+
);
|
|
20526
|
+
this.auditLog.append(
|
|
20527
|
+
"l2",
|
|
20528
|
+
APPROVAL_AGGREGATOR_AUDIT_OPS.AUDIT_TRAIL_VIEWED,
|
|
20529
|
+
operatorId,
|
|
20530
|
+
{
|
|
20531
|
+
aggregator_id: aggregatorId,
|
|
20532
|
+
entry_status: entry.status,
|
|
20533
|
+
match_count: matches.length
|
|
20534
|
+
}
|
|
20535
|
+
);
|
|
20536
|
+
return matches;
|
|
20537
|
+
}
|
|
20538
|
+
/**
|
|
20539
|
+
* List historical (resolved) approvals. Excludes pending entries by
|
|
20540
|
+
* design: `list()` is the pending-inbox surface and `getHistory()` is
|
|
20541
|
+
* the resolved-replay surface. Emits REPLAYED on each call. v1.3
|
|
20542
|
+
* Upsilon-3.
|
|
20543
|
+
*/
|
|
20544
|
+
async getHistory(opts, operatorId) {
|
|
20545
|
+
await this.hydrate();
|
|
20546
|
+
await this.expireStale();
|
|
20547
|
+
const limit = Math.min(
|
|
20548
|
+
opts?.limit ?? DEFAULT_LIST_PAGE_SIZE,
|
|
20549
|
+
this.maxListLimit
|
|
20550
|
+
);
|
|
20551
|
+
const sinceMs = opts?.sinceTs ? Date.parse(opts.sinceTs) : Number.NEGATIVE_INFINITY;
|
|
20552
|
+
const matching = [];
|
|
20553
|
+
for (const entry of this.entries.values()) {
|
|
20554
|
+
if (entry.status === "pending") continue;
|
|
20555
|
+
if (opts?.status && entry.status !== opts.status) continue;
|
|
20556
|
+
const stamp = Date.parse(entry.resolved_at ?? entry.created_at);
|
|
20557
|
+
if (stamp < sinceMs) continue;
|
|
20558
|
+
matching.push(entry);
|
|
20559
|
+
}
|
|
20560
|
+
matching.sort((a, b) => {
|
|
20561
|
+
const aStamp = a.resolved_at ?? a.created_at;
|
|
20562
|
+
const bStamp = b.resolved_at ?? b.created_at;
|
|
20563
|
+
return bStamp.localeCompare(aStamp);
|
|
20564
|
+
});
|
|
20565
|
+
const sliced = matching.slice(0, limit);
|
|
20566
|
+
this.auditLog.append(
|
|
20567
|
+
"l2",
|
|
20568
|
+
APPROVAL_AGGREGATOR_AUDIT_OPS.REPLAYED,
|
|
20569
|
+
operatorId,
|
|
20570
|
+
{
|
|
20571
|
+
result_count: sliced.length,
|
|
20572
|
+
...opts?.status !== void 0 ? { status_filter: opts.status } : {},
|
|
20573
|
+
...opts?.sinceTs !== void 0 ? { since: opts.sinceTs } : {}
|
|
20574
|
+
}
|
|
20575
|
+
);
|
|
20576
|
+
return sliced;
|
|
20376
20577
|
}
|
|
20377
20578
|
/**
|
|
20378
20579
|
* Resolve an entry. Used by both:
|
|
@@ -20446,6 +20647,7 @@ var init_approval_aggregator = __esm({
|
|
|
20446
20647
|
const now = this.now();
|
|
20447
20648
|
const expires = new Date(now.getTime() + this.pendingTtlMs);
|
|
20448
20649
|
const hubInboxId = this.resolveHubInboxItemId(event);
|
|
20650
|
+
const enforcementChain = this.resolveEnforcementChain(event);
|
|
20449
20651
|
const entry = {
|
|
20450
20652
|
aggregator_id: id,
|
|
20451
20653
|
source_harness: ctx.source_harness,
|
|
@@ -20457,13 +20659,20 @@ var init_approval_aggregator = __esm({
|
|
|
20457
20659
|
status: "pending",
|
|
20458
20660
|
created_at: now.toISOString(),
|
|
20459
20661
|
expires_at: expires.toISOString(),
|
|
20460
|
-
...hubInboxId !== void 0 ? { hub_inbox_item_id: hubInboxId } : {}
|
|
20662
|
+
...hubInboxId !== void 0 ? { hub_inbox_item_id: hubInboxId } : {},
|
|
20663
|
+
...enforcementChain.length > 0 ? { enforcement_chain: enforcementChain } : {}
|
|
20461
20664
|
};
|
|
20462
20665
|
this.entries.set(id, entry);
|
|
20463
20666
|
this.dedupIndex.set(dedupKey, id);
|
|
20464
20667
|
this.correlationIndex.set(event.correlation_id, id);
|
|
20465
20668
|
this.fullPayloads.set(id, event.context);
|
|
20466
20669
|
await this.persist(entry);
|
|
20670
|
+
if (this.payloadStore) {
|
|
20671
|
+
try {
|
|
20672
|
+
await this.payloadStore.savePayload(id, event.context);
|
|
20673
|
+
} catch {
|
|
20674
|
+
}
|
|
20675
|
+
}
|
|
20467
20676
|
this.auditLog.append(
|
|
20468
20677
|
"l2",
|
|
20469
20678
|
APPROVAL_AGGREGATOR_AUDIT_OPS.AGGREGATED,
|
|
@@ -20779,6 +20988,149 @@ var init_aggregator_backed_channel = __esm({
|
|
|
20779
20988
|
}
|
|
20780
20989
|
});
|
|
20781
20990
|
|
|
20991
|
+
// src/principal-policy/aggregator-store.ts
|
|
20992
|
+
function payloadKey(aggregatorId) {
|
|
20993
|
+
return `${AGGREGATOR_PAYLOAD_KEY_PREFIX}${aggregatorId}`;
|
|
20994
|
+
}
|
|
20995
|
+
function stripKeyPrefix(key) {
|
|
20996
|
+
if (!key.startsWith(AGGREGATOR_PAYLOAD_KEY_PREFIX)) return null;
|
|
20997
|
+
return key.slice(AGGREGATOR_PAYLOAD_KEY_PREFIX.length);
|
|
20998
|
+
}
|
|
20999
|
+
var AGGREGATOR_PAYLOAD_NAMESPACE, AGGREGATOR_PAYLOAD_KEY_PREFIX, HKDF_INFO, DEFAULT_AGGREGATOR_PAYLOAD_RETENTION_DAYS, MAX_BUNDLE_BYTES2, AggregatorPayloadStore;
|
|
21000
|
+
var init_aggregator_store = __esm({
|
|
21001
|
+
"src/principal-policy/aggregator-store.ts"() {
|
|
21002
|
+
init_encryption();
|
|
21003
|
+
init_key_derivation();
|
|
21004
|
+
init_encoding();
|
|
21005
|
+
AGGREGATOR_PAYLOAD_NAMESPACE = "_approval_aggregator_payloads";
|
|
21006
|
+
AGGREGATOR_PAYLOAD_KEY_PREFIX = "payload.";
|
|
21007
|
+
HKDF_INFO = "l2-approval-aggregator-payload-v1";
|
|
21008
|
+
DEFAULT_AGGREGATOR_PAYLOAD_RETENTION_DAYS = 30;
|
|
21009
|
+
MAX_BUNDLE_BYTES2 = 4 * 1024 * 1024;
|
|
21010
|
+
AggregatorPayloadStore = class {
|
|
21011
|
+
storage;
|
|
21012
|
+
encryptionKey;
|
|
21013
|
+
fortressId;
|
|
21014
|
+
retentionDays;
|
|
21015
|
+
constructor(opts) {
|
|
21016
|
+
this.storage = opts.storage;
|
|
21017
|
+
this.encryptionKey = derivePurposeKey(opts.masterKey, HKDF_INFO);
|
|
21018
|
+
this.fortressId = opts.fortressId;
|
|
21019
|
+
this.retentionDays = opts.retentionDays !== void 0 && opts.retentionDays > 0 ? opts.retentionDays : DEFAULT_AGGREGATOR_PAYLOAD_RETENTION_DAYS;
|
|
21020
|
+
}
|
|
21021
|
+
/**
|
|
21022
|
+
* Persist `payload` under the given aggregator_id. Idempotent; calling
|
|
21023
|
+
* twice with the same id rewrites the bundle (retention_until is
|
|
21024
|
+
* recomputed). Returns the bundle's retention_until ISO-8601 timestamp
|
|
21025
|
+
* so callers can log it.
|
|
21026
|
+
*/
|
|
21027
|
+
async savePayload(aggregatorId, payload) {
|
|
21028
|
+
const now = /* @__PURE__ */ new Date();
|
|
21029
|
+
const retentionMs = this.retentionDays * 24 * 60 * 60 * 1e3;
|
|
21030
|
+
const retentionUntil = new Date(now.getTime() + retentionMs);
|
|
21031
|
+
const bundle = {
|
|
21032
|
+
version: 1,
|
|
21033
|
+
aggregator_id: aggregatorId,
|
|
21034
|
+
fortress_id: this.fortressId,
|
|
21035
|
+
created_at: now.toISOString(),
|
|
21036
|
+
retention_until: retentionUntil.toISOString(),
|
|
21037
|
+
payload
|
|
21038
|
+
};
|
|
21039
|
+
const aad = stringToBytes(aggregatorId);
|
|
21040
|
+
const plaintext = stringToBytes(JSON.stringify(bundle));
|
|
21041
|
+
const envelope = encrypt(plaintext, this.encryptionKey, aad);
|
|
21042
|
+
await this.storage.write(
|
|
21043
|
+
AGGREGATOR_PAYLOAD_NAMESPACE,
|
|
21044
|
+
payloadKey(aggregatorId),
|
|
21045
|
+
stringToBytes(JSON.stringify(envelope))
|
|
21046
|
+
);
|
|
21047
|
+
return bundle.retention_until;
|
|
21048
|
+
}
|
|
21049
|
+
/**
|
|
21050
|
+
* Read the persisted payload for the aggregator_id. Returns null if no
|
|
21051
|
+
* bundle exists, the bundle is corrupted, or AAD binding fails.
|
|
21052
|
+
*/
|
|
21053
|
+
async loadPayload(aggregatorId) {
|
|
21054
|
+
const key = payloadKey(aggregatorId);
|
|
21055
|
+
let raw;
|
|
21056
|
+
try {
|
|
21057
|
+
raw = await this.storage.read(AGGREGATOR_PAYLOAD_NAMESPACE, key);
|
|
21058
|
+
} catch {
|
|
21059
|
+
return null;
|
|
21060
|
+
}
|
|
21061
|
+
if (!raw) return null;
|
|
21062
|
+
if (raw.length > MAX_BUNDLE_BYTES2) return null;
|
|
21063
|
+
try {
|
|
21064
|
+
const envelope = JSON.parse(bytesToString(raw));
|
|
21065
|
+
const aad = stringToBytes(aggregatorId);
|
|
21066
|
+
const plaintext = decrypt(envelope, this.encryptionKey, aad);
|
|
21067
|
+
const parsed = JSON.parse(
|
|
21068
|
+
bytesToString(plaintext)
|
|
21069
|
+
);
|
|
21070
|
+
if (parsed.version !== 1) return null;
|
|
21071
|
+
if (parsed.aggregator_id !== aggregatorId) return null;
|
|
21072
|
+
return parsed.payload;
|
|
21073
|
+
} catch {
|
|
21074
|
+
return null;
|
|
21075
|
+
}
|
|
21076
|
+
}
|
|
21077
|
+
/**
|
|
21078
|
+
* Delete the persisted payload. Returns true when a bundle was removed,
|
|
21079
|
+
* false when none existed.
|
|
21080
|
+
*/
|
|
21081
|
+
async deletePayload(aggregatorId) {
|
|
21082
|
+
const key = payloadKey(aggregatorId);
|
|
21083
|
+
const existed = await this.storage.exists(
|
|
21084
|
+
AGGREGATOR_PAYLOAD_NAMESPACE,
|
|
21085
|
+
key
|
|
21086
|
+
);
|
|
21087
|
+
if (!existed) return false;
|
|
21088
|
+
try {
|
|
21089
|
+
await this.storage.delete(AGGREGATOR_PAYLOAD_NAMESPACE, key);
|
|
21090
|
+
} catch {
|
|
21091
|
+
return false;
|
|
21092
|
+
}
|
|
21093
|
+
return true;
|
|
21094
|
+
}
|
|
21095
|
+
/**
|
|
21096
|
+
* Drop expired payload bundles. Returns the count of bundles pruned.
|
|
21097
|
+
* Caller wires this into the cocoon-unlock initialization path.
|
|
21098
|
+
*/
|
|
21099
|
+
async pruneExpired(now) {
|
|
21100
|
+
const cutoff = (now ?? /* @__PURE__ */ new Date()).toISOString();
|
|
21101
|
+
const entries = await this.storage.list(
|
|
21102
|
+
AGGREGATOR_PAYLOAD_NAMESPACE,
|
|
21103
|
+
AGGREGATOR_PAYLOAD_KEY_PREFIX
|
|
21104
|
+
);
|
|
21105
|
+
let pruned = 0;
|
|
21106
|
+
for (const meta of entries) {
|
|
21107
|
+
const aggregatorId = stripKeyPrefix(meta.key);
|
|
21108
|
+
if (aggregatorId === null) continue;
|
|
21109
|
+
const raw = await this.storage.read(
|
|
21110
|
+
AGGREGATOR_PAYLOAD_NAMESPACE,
|
|
21111
|
+
meta.key
|
|
21112
|
+
);
|
|
21113
|
+
if (!raw) continue;
|
|
21114
|
+
try {
|
|
21115
|
+
const envelope = JSON.parse(bytesToString(raw));
|
|
21116
|
+
const aad = stringToBytes(aggregatorId);
|
|
21117
|
+
const plaintext = decrypt(envelope, this.encryptionKey, aad);
|
|
21118
|
+
const parsed = JSON.parse(
|
|
21119
|
+
bytesToString(plaintext)
|
|
21120
|
+
);
|
|
21121
|
+
if (parsed.retention_until <= cutoff) {
|
|
21122
|
+
await this.storage.delete(AGGREGATOR_PAYLOAD_NAMESPACE, meta.key);
|
|
21123
|
+
pruned += 1;
|
|
21124
|
+
}
|
|
21125
|
+
} catch {
|
|
21126
|
+
}
|
|
21127
|
+
}
|
|
21128
|
+
return { pruned };
|
|
21129
|
+
}
|
|
21130
|
+
};
|
|
21131
|
+
}
|
|
21132
|
+
});
|
|
21133
|
+
|
|
20782
21134
|
// src/principal-policy/tools.ts
|
|
20783
21135
|
function createPrincipalPolicyTools(policy, baseline, auditLog) {
|
|
20784
21136
|
return [
|
|
@@ -33397,7 +33749,14 @@ var init_operator_chat_audit_events = __esm({
|
|
|
33397
33749
|
* turns; the concierge degrades to single-turn after emitting. Body
|
|
33398
33750
|
* carries thread_id + a stable failure_reason enum.
|
|
33399
33751
|
*/
|
|
33400
|
-
CONCIERGE_MEMORY_READ_FAILED: "operator_concierge_memory_read_failed"
|
|
33752
|
+
CONCIERGE_MEMORY_READ_FAILED: "operator_concierge_memory_read_failed",
|
|
33753
|
+
/**
|
|
33754
|
+
* Concierge dynamic-context fetcher failed (WP-V1.3-9 Tau-3). Emitted
|
|
33755
|
+
* when a category fetcher throws while assembling the dynamic context
|
|
33756
|
+
* fold. The concierge omits that category and continues; the user-
|
|
33757
|
+
* facing query is never broken. Body carries category + failure_reason.
|
|
33758
|
+
*/
|
|
33759
|
+
CONCIERGE_CONTEXT_FETCHER_FAILED: "operator_concierge_context_fetcher_failed"
|
|
33401
33760
|
};
|
|
33402
33761
|
}
|
|
33403
33762
|
});
|
|
@@ -33410,12 +33769,291 @@ var init_operator_chat_types = __esm({
|
|
|
33410
33769
|
CONCIERGE_THREAD_KEY = "_fortress";
|
|
33411
33770
|
}
|
|
33412
33771
|
});
|
|
33772
|
+
|
|
33773
|
+
// src/chat/concierge-context-router.ts
|
|
33774
|
+
function phrasePattern(phrase) {
|
|
33775
|
+
const escaped = phrase.toLowerCase().split(/\s+/).map((w) => w.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("\\s+");
|
|
33776
|
+
return { source: `\\b${escaped}\\b`, phrase };
|
|
33777
|
+
}
|
|
33778
|
+
function extractAgentNameHint(query) {
|
|
33779
|
+
const agentPattern = /\bagent\s+["']?([A-Za-z][\w-]{0,40})["']?/i;
|
|
33780
|
+
const m = query.match(agentPattern);
|
|
33781
|
+
if (m && m[1]) return m[1];
|
|
33782
|
+
const quoted = query.match(/["']([A-Za-z][\w-]{0,40})["']/);
|
|
33783
|
+
if (quoted && quoted[1]) return quoted[1];
|
|
33784
|
+
return null;
|
|
33785
|
+
}
|
|
33786
|
+
function isTrivialQuery(query) {
|
|
33787
|
+
const norm = query.trim().toLowerCase();
|
|
33788
|
+
if (norm.length === 0) return true;
|
|
33789
|
+
if (norm.length < 8) return true;
|
|
33790
|
+
return TRIVIAL_GREETINGS.has(norm);
|
|
33791
|
+
}
|
|
33792
|
+
function classifyQuery(query) {
|
|
33793
|
+
const normalized = query.toLowerCase();
|
|
33794
|
+
const matches = [];
|
|
33795
|
+
for (const spec of CATEGORY_KEYWORDS) {
|
|
33796
|
+
const matchedPhrases = [];
|
|
33797
|
+
for (const pattern of spec.patterns) {
|
|
33798
|
+
if (matchedPhrases.includes(pattern.phrase)) continue;
|
|
33799
|
+
const re = new RegExp(pattern.source, "i");
|
|
33800
|
+
if (re.test(normalized)) {
|
|
33801
|
+
matchedPhrases.push(pattern.phrase);
|
|
33802
|
+
}
|
|
33803
|
+
}
|
|
33804
|
+
if (matchedPhrases.length === 0) continue;
|
|
33805
|
+
const confidence = Math.min(1, 0.4 + 0.3 * matchedPhrases.length);
|
|
33806
|
+
matches.push({
|
|
33807
|
+
category: spec.category,
|
|
33808
|
+
confidence,
|
|
33809
|
+
matched_keywords: matchedPhrases,
|
|
33810
|
+
agent_name_hint: spec.category === "agent_state" || spec.category === "agent_activity" ? extractAgentNameHint(query) : null
|
|
33811
|
+
});
|
|
33812
|
+
}
|
|
33813
|
+
matches.sort((a, b) => {
|
|
33814
|
+
if (b.confidence !== a.confidence) return b.confidence - a.confidence;
|
|
33815
|
+
return CONTEXT_CATEGORIES.indexOf(a.category) - CONTEXT_CATEGORIES.indexOf(b.category);
|
|
33816
|
+
});
|
|
33817
|
+
return matches;
|
|
33818
|
+
}
|
|
33413
33819
|
function approxTokenLen(text) {
|
|
33820
|
+
return Math.ceil(text.length / APPROX_CHARS_PER_TOKEN);
|
|
33821
|
+
}
|
|
33822
|
+
async function runFetcher(match, fetchers) {
|
|
33823
|
+
switch (match.category) {
|
|
33824
|
+
case "templates":
|
|
33825
|
+
return fetchers.templates();
|
|
33826
|
+
case "agent_state":
|
|
33827
|
+
return fetchers.agent_state(match.agent_name_hint);
|
|
33828
|
+
case "agent_activity":
|
|
33829
|
+
return fetchers.agent_activity(match.agent_name_hint);
|
|
33830
|
+
case "audit_log":
|
|
33831
|
+
return fetchers.audit_log();
|
|
33832
|
+
case "sentinel_findings":
|
|
33833
|
+
return fetchers.sentinel_findings();
|
|
33834
|
+
case "anomaly_alerts":
|
|
33835
|
+
return fetchers.anomaly_alerts();
|
|
33836
|
+
case "recent_receipts":
|
|
33837
|
+
return fetchers.recent_receipts();
|
|
33838
|
+
case "verascore_deltas":
|
|
33839
|
+
return fetchers.verascore_deltas();
|
|
33840
|
+
}
|
|
33841
|
+
}
|
|
33842
|
+
function trivialMatch(category) {
|
|
33843
|
+
return {
|
|
33844
|
+
category,
|
|
33845
|
+
confidence: 0.5,
|
|
33846
|
+
matched_keywords: ["llm-assist"],
|
|
33847
|
+
agent_name_hint: null
|
|
33848
|
+
};
|
|
33849
|
+
}
|
|
33850
|
+
async function foldContext(query, fetchers, opts) {
|
|
33851
|
+
const budget = opts?.maxTokens ?? DEFAULT_DYNAMIC_CONTEXT_TOKEN_BUDGET;
|
|
33852
|
+
let matches = classifyQuery(query);
|
|
33853
|
+
if (matches.length === 0 && !isTrivialQuery(query) && opts?.llmAssistClassify) {
|
|
33854
|
+
try {
|
|
33855
|
+
const picked = await opts.llmAssistClassify(query, CONTEXT_CATEGORIES);
|
|
33856
|
+
if (picked !== "none" && CONTEXT_CATEGORIES.includes(picked)) {
|
|
33857
|
+
matches = [trivialMatch(picked)];
|
|
33858
|
+
}
|
|
33859
|
+
} catch {
|
|
33860
|
+
}
|
|
33861
|
+
}
|
|
33862
|
+
if (matches.length === 0) {
|
|
33863
|
+
return { section: "", categoriesIncluded: [] };
|
|
33864
|
+
}
|
|
33865
|
+
const attempts = [];
|
|
33866
|
+
for (const match of matches) {
|
|
33867
|
+
try {
|
|
33868
|
+
const text = await runFetcher(match, fetchers);
|
|
33869
|
+
const trimmed = text.trim();
|
|
33870
|
+
if (trimmed.length > 0) {
|
|
33871
|
+
attempts.push({ category: match.category, text: trimmed });
|
|
33872
|
+
}
|
|
33873
|
+
} catch (err) {
|
|
33874
|
+
opts?.onFetcherFailure?.(match.category, err);
|
|
33875
|
+
}
|
|
33876
|
+
}
|
|
33877
|
+
if (attempts.length === 0) {
|
|
33878
|
+
return { section: "", categoriesIncluded: [] };
|
|
33879
|
+
}
|
|
33880
|
+
const headerTokens = approxTokenLen(`${DYNAMIC_CONTEXT_SECTION_HEADER}
|
|
33881
|
+
`);
|
|
33882
|
+
const sepTokens = approxTokenLen("\n\n");
|
|
33883
|
+
let runningTokens = headerTokens;
|
|
33884
|
+
const kept = [];
|
|
33885
|
+
for (const attempt of attempts) {
|
|
33886
|
+
const block = `### ${CATEGORY_LABELS[attempt.category]}
|
|
33887
|
+
${attempt.text}`;
|
|
33888
|
+
const tokens = approxTokenLen(block) + (kept.length > 0 ? sepTokens : 0);
|
|
33889
|
+
if (kept.length === 0) {
|
|
33890
|
+
kept.push(attempt);
|
|
33891
|
+
runningTokens += tokens;
|
|
33892
|
+
continue;
|
|
33893
|
+
}
|
|
33894
|
+
if (runningTokens + tokens > budget) break;
|
|
33895
|
+
kept.push(attempt);
|
|
33896
|
+
runningTokens += tokens;
|
|
33897
|
+
}
|
|
33898
|
+
const blocks = kept.map(
|
|
33899
|
+
(k) => `### ${CATEGORY_LABELS[k.category]}
|
|
33900
|
+
${k.text}`
|
|
33901
|
+
);
|
|
33902
|
+
const section = `${DYNAMIC_CONTEXT_SECTION_HEADER}
|
|
33903
|
+
${blocks.join("\n\n")}`;
|
|
33904
|
+
return {
|
|
33905
|
+
section,
|
|
33906
|
+
categoriesIncluded: kept.map((k) => k.category)
|
|
33907
|
+
};
|
|
33908
|
+
}
|
|
33909
|
+
var APPROX_CHARS_PER_TOKEN, DEFAULT_DYNAMIC_CONTEXT_TOKEN_BUDGET, DYNAMIC_CONTEXT_SECTION_HEADER, CONTEXT_CATEGORIES, CATEGORY_KEYWORDS, TRIVIAL_GREETINGS, CATEGORY_LABELS;
|
|
33910
|
+
var init_concierge_context_router = __esm({
|
|
33911
|
+
"src/chat/concierge-context-router.ts"() {
|
|
33912
|
+
APPROX_CHARS_PER_TOKEN = 4;
|
|
33913
|
+
DEFAULT_DYNAMIC_CONTEXT_TOKEN_BUDGET = 2e3;
|
|
33914
|
+
DYNAMIC_CONTEXT_SECTION_HEADER = "## Live fortress context";
|
|
33915
|
+
CONTEXT_CATEGORIES = [
|
|
33916
|
+
"templates",
|
|
33917
|
+
"agent_state",
|
|
33918
|
+
"agent_activity",
|
|
33919
|
+
"audit_log",
|
|
33920
|
+
"sentinel_findings",
|
|
33921
|
+
"anomaly_alerts",
|
|
33922
|
+
"recent_receipts",
|
|
33923
|
+
"verascore_deltas"
|
|
33924
|
+
];
|
|
33925
|
+
CATEGORY_KEYWORDS = [
|
|
33926
|
+
{
|
|
33927
|
+
category: "templates",
|
|
33928
|
+
patterns: [
|
|
33929
|
+
"templates",
|
|
33930
|
+
"template",
|
|
33931
|
+
"channel templates",
|
|
33932
|
+
"channel template",
|
|
33933
|
+
"list templates",
|
|
33934
|
+
"available templates",
|
|
33935
|
+
"what templates"
|
|
33936
|
+
].map(phrasePattern)
|
|
33937
|
+
},
|
|
33938
|
+
{
|
|
33939
|
+
category: "agent_state",
|
|
33940
|
+
patterns: [
|
|
33941
|
+
"state",
|
|
33942
|
+
"status",
|
|
33943
|
+
"agent state",
|
|
33944
|
+
"agent status",
|
|
33945
|
+
"status of agent",
|
|
33946
|
+
"status of agents",
|
|
33947
|
+
"state of",
|
|
33948
|
+
"doing"
|
|
33949
|
+
].map(phrasePattern)
|
|
33950
|
+
},
|
|
33951
|
+
{
|
|
33952
|
+
category: "agent_activity",
|
|
33953
|
+
patterns: [
|
|
33954
|
+
"activity",
|
|
33955
|
+
"agent activity",
|
|
33956
|
+
"what did",
|
|
33957
|
+
"recent activity"
|
|
33958
|
+
].map(phrasePattern)
|
|
33959
|
+
},
|
|
33960
|
+
{
|
|
33961
|
+
category: "audit_log",
|
|
33962
|
+
patterns: [
|
|
33963
|
+
"audit log",
|
|
33964
|
+
"audit",
|
|
33965
|
+
"log entry",
|
|
33966
|
+
"log entries",
|
|
33967
|
+
"what happened",
|
|
33968
|
+
"show me events",
|
|
33969
|
+
"event class"
|
|
33970
|
+
].map(phrasePattern)
|
|
33971
|
+
},
|
|
33972
|
+
{
|
|
33973
|
+
category: "sentinel_findings",
|
|
33974
|
+
patterns: [
|
|
33975
|
+
"sentinel",
|
|
33976
|
+
"sentinels",
|
|
33977
|
+
"warning",
|
|
33978
|
+
"warnings",
|
|
33979
|
+
"alert",
|
|
33980
|
+
"alerts",
|
|
33981
|
+
"whats wrong",
|
|
33982
|
+
"what's wrong",
|
|
33983
|
+
"findings"
|
|
33984
|
+
].map(phrasePattern)
|
|
33985
|
+
},
|
|
33986
|
+
{
|
|
33987
|
+
category: "anomaly_alerts",
|
|
33988
|
+
patterns: [
|
|
33989
|
+
"anomaly",
|
|
33990
|
+
"anomalies",
|
|
33991
|
+
"spike",
|
|
33992
|
+
"unusual",
|
|
33993
|
+
"outlier"
|
|
33994
|
+
].map(phrasePattern)
|
|
33995
|
+
},
|
|
33996
|
+
{
|
|
33997
|
+
category: "recent_receipts",
|
|
33998
|
+
patterns: [
|
|
33999
|
+
"receipt",
|
|
34000
|
+
"receipts",
|
|
34001
|
+
"concordia",
|
|
34002
|
+
"commitment",
|
|
34003
|
+
"commitments",
|
|
34004
|
+
"chain",
|
|
34005
|
+
"chains"
|
|
34006
|
+
].map(phrasePattern)
|
|
34007
|
+
},
|
|
34008
|
+
{
|
|
34009
|
+
category: "verascore_deltas",
|
|
34010
|
+
patterns: [
|
|
34011
|
+
"verascore",
|
|
34012
|
+
"vera score",
|
|
34013
|
+
"trust score",
|
|
34014
|
+
"reputation"
|
|
34015
|
+
].map(phrasePattern)
|
|
34016
|
+
}
|
|
34017
|
+
];
|
|
34018
|
+
TRIVIAL_GREETINGS = /* @__PURE__ */ new Set([
|
|
34019
|
+
"hi",
|
|
34020
|
+
"hello",
|
|
34021
|
+
"hey",
|
|
34022
|
+
"yo",
|
|
34023
|
+
"ok",
|
|
34024
|
+
"thanks",
|
|
34025
|
+
"thx",
|
|
34026
|
+
"thank you"
|
|
34027
|
+
]);
|
|
34028
|
+
CATEGORY_LABELS = {
|
|
34029
|
+
templates: "Templates",
|
|
34030
|
+
agent_state: "Agent state",
|
|
34031
|
+
agent_activity: "Agent activity",
|
|
34032
|
+
audit_log: "Audit log",
|
|
34033
|
+
sentinel_findings: "Sentinel findings",
|
|
34034
|
+
anomaly_alerts: "Anomaly alerts",
|
|
34035
|
+
recent_receipts: "Recent receipts",
|
|
34036
|
+
verascore_deltas: "Verascore deltas"
|
|
34037
|
+
};
|
|
34038
|
+
}
|
|
34039
|
+
});
|
|
34040
|
+
function approxTokenLen2(text) {
|
|
33414
34041
|
return Math.ceil(text.length / 4);
|
|
33415
34042
|
}
|
|
33416
34043
|
function makeEventId(prefix) {
|
|
33417
34044
|
return `${prefix}-${Date.now()}-${randomUUID().slice(0, 8)}`;
|
|
33418
34045
|
}
|
|
34046
|
+
function classifyFetcherError(error) {
|
|
34047
|
+
const msg = error instanceof Error ? error.message.toLowerCase() : String(error).toLowerCase();
|
|
34048
|
+
if (msg.includes("timeout") || msg.includes("timed out")) return "timeout";
|
|
34049
|
+
if (msg.includes("schema") || msg.includes("invalid shape")) {
|
|
34050
|
+
return "schema_mismatch";
|
|
34051
|
+
}
|
|
34052
|
+
if (msg.includes("io") || msg.includes("read") || msg.includes("enoent") || msg.includes("eacces")) {
|
|
34053
|
+
return "io_failed";
|
|
34054
|
+
}
|
|
34055
|
+
return "unknown";
|
|
34056
|
+
}
|
|
33419
34057
|
function formatPriorTurnLine(turn) {
|
|
33420
34058
|
const label = turn.role === "user" ? "OPERATOR" : "CONCIERGE";
|
|
33421
34059
|
return `${label}: ${turn.content}`;
|
|
@@ -33423,18 +34061,20 @@ function formatPriorTurnLine(turn) {
|
|
|
33423
34061
|
function hashOf(input) {
|
|
33424
34062
|
return hashToString(sha256(stringToBytes(input)));
|
|
33425
34063
|
}
|
|
33426
|
-
var DEFAULT_CONCIERGE_MAX_TOKENS, DEFAULT_CONCIERGE_HISTORY_WINDOW_TURNS, DEFAULT_CONCIERGE_HISTORY_FRESHNESS_MS, DEFAULT_CONCIERGE_HISTORY_TOKEN_BUDGET, DEFAULT_CONCIERGE_SESSION_TTL_MS, SANCTUARY_DOMAIN_REFERENCE, OperatorChatService;
|
|
34064
|
+
var DEFAULT_CONCIERGE_MAX_TOKENS, DEFAULT_CONCIERGE_HISTORY_WINDOW_TURNS, DEFAULT_CONCIERGE_HISTORY_FRESHNESS_MS, DEFAULT_CONCIERGE_HISTORY_TOKEN_BUDGET, DEFAULT_CONCIERGE_SESSION_TTL_MS, DEFAULT_CONCIERGE_DYNAMIC_CONTEXT_BUDGET, SANCTUARY_DOMAIN_REFERENCE, OperatorChatService;
|
|
33427
34065
|
var init_operator_chat_service = __esm({
|
|
33428
34066
|
"src/chat/operator-chat-service.ts"() {
|
|
33429
34067
|
init_hashing();
|
|
33430
34068
|
init_encoding();
|
|
33431
34069
|
init_operator_chat_audit_events();
|
|
33432
34070
|
init_operator_chat_types();
|
|
34071
|
+
init_concierge_context_router();
|
|
33433
34072
|
DEFAULT_CONCIERGE_MAX_TOKENS = 512;
|
|
33434
34073
|
DEFAULT_CONCIERGE_HISTORY_WINDOW_TURNS = 10;
|
|
33435
34074
|
DEFAULT_CONCIERGE_HISTORY_FRESHNESS_MS = 24 * 60 * 60 * 1e3;
|
|
33436
34075
|
DEFAULT_CONCIERGE_HISTORY_TOKEN_BUDGET = 500;
|
|
33437
34076
|
DEFAULT_CONCIERGE_SESSION_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
34077
|
+
DEFAULT_CONCIERGE_DYNAMIC_CONTEXT_BUDGET = 2e3;
|
|
33438
34078
|
SANCTUARY_DOMAIN_REFERENCE = `Castle Architecture (four enforcement layers):
|
|
33439
34079
|
1. Castle Wall: OS-boundary egress filter enforced at the kernel level. Blocks unauthorized outbound calls even from prompt-injected agents.
|
|
33440
34080
|
2. Sentinels: internal observation via process introspection. Surfaces anomalies to the operator; does not enforce.
|
|
@@ -33476,6 +34116,9 @@ Note: this is a static reference block (v1.2.x). Dynamic context injection (live
|
|
|
33476
34116
|
historyTokenBudget;
|
|
33477
34117
|
sessionTtlMs;
|
|
33478
34118
|
clock;
|
|
34119
|
+
contextFetchers;
|
|
34120
|
+
contextLlmAssist;
|
|
34121
|
+
dynamicContextBudget;
|
|
33479
34122
|
/**
|
|
33480
34123
|
* In-memory thread_id assigned to the active concierge session.
|
|
33481
34124
|
* The first sendConcierge call after construction allocates a fresh
|
|
@@ -33507,6 +34150,13 @@ Note: this is a static reference block (v1.2.x). Dynamic context injection (live
|
|
|
33507
34150
|
this.historyTokenBudget = deps.conciergeHistoryTokenBudget !== void 0 && deps.conciergeHistoryTokenBudget > 0 ? deps.conciergeHistoryTokenBudget : DEFAULT_CONCIERGE_HISTORY_TOKEN_BUDGET;
|
|
33508
34151
|
this.sessionTtlMs = deps.conciergeSessionTtlMs !== void 0 && deps.conciergeSessionTtlMs > 0 ? deps.conciergeSessionTtlMs : DEFAULT_CONCIERGE_SESSION_TTL_MS;
|
|
33509
34152
|
this.clock = deps.conciergeClock ?? (() => Date.now());
|
|
34153
|
+
if (deps.conciergeContextFetchers) {
|
|
34154
|
+
this.contextFetchers = deps.conciergeContextFetchers;
|
|
34155
|
+
}
|
|
34156
|
+
if (deps.conciergeContextLlmAssist) {
|
|
34157
|
+
this.contextLlmAssist = deps.conciergeContextLlmAssist;
|
|
34158
|
+
}
|
|
34159
|
+
this.dynamicContextBudget = deps.conciergeDynamicContextBudget !== void 0 && deps.conciergeDynamicContextBudget > 0 ? deps.conciergeDynamicContextBudget : DEFAULT_CONCIERGE_DYNAMIC_CONTEXT_BUDGET;
|
|
33510
34160
|
}
|
|
33511
34161
|
// ── Concierge ─────────────────────────────────────────────────────────
|
|
33512
34162
|
/**
|
|
@@ -33570,6 +34220,7 @@ Note: this is a static reference block (v1.2.x). Dynamic context injection (live
|
|
|
33570
34220
|
let servedBy = "disabled";
|
|
33571
34221
|
let displayLabel = "Concierge: substrate not configured";
|
|
33572
34222
|
let outcome = "substrate_disabled";
|
|
34223
|
+
let dynamicCategoriesIncluded = [];
|
|
33573
34224
|
if (!this.substrateSelector) {
|
|
33574
34225
|
conciergeBody = "Concierge unavailable. The substrate selector is not configured for this fortress. Pick a substrate in the Policy center to enable concierge replies.";
|
|
33575
34226
|
} else {
|
|
@@ -33581,7 +34232,14 @@ Note: this is a static reference block (v1.2.x). Dynamic context injection (live
|
|
|
33581
34232
|
conciergeBody = "Concierge unavailable. The chosen substrate does not support summarization. Pick a different substrate in the Policy center.";
|
|
33582
34233
|
outcome = "substrate_disabled";
|
|
33583
34234
|
} else {
|
|
33584
|
-
const
|
|
34235
|
+
const dynamicResult = await this.runDynamicContextFold(
|
|
34236
|
+
filterResult.filtered
|
|
34237
|
+
);
|
|
34238
|
+
dynamicCategoriesIncluded = dynamicResult.categoriesIncluded;
|
|
34239
|
+
const context = await this.assembleConciergeContext(
|
|
34240
|
+
priorTurns,
|
|
34241
|
+
dynamicResult.section
|
|
34242
|
+
);
|
|
33585
34243
|
const response = await this.substrateSelector.invokeSummarize(
|
|
33586
34244
|
"concierge",
|
|
33587
34245
|
{
|
|
@@ -33645,7 +34303,8 @@ Note: this is a static reference block (v1.2.x). Dynamic context injection (live
|
|
|
33645
34303
|
...assistantTurnId !== void 0 ? { turn_index: assistantTurnId } : {},
|
|
33646
34304
|
...this.memory ? {
|
|
33647
34305
|
prior_turns_folded: memoryReadFailureReason === null ? priorTurns.length : 0
|
|
33648
|
-
} : {}
|
|
34306
|
+
} : {},
|
|
34307
|
+
...this.contextFetchers ? { dynamic_context_categories: [...dynamicCategoriesIncluded] } : {}
|
|
33649
34308
|
};
|
|
33650
34309
|
this.emit(OPERATOR_CHAT_OPS.CONCIERGE_CHAT, payload, outcome === "ok" ? "success" : "failure");
|
|
33651
34310
|
return {
|
|
@@ -33796,10 +34455,13 @@ Note: this is a static reference block (v1.2.x). Dynamic context injection (live
|
|
|
33796
34455
|
* ## Sanctuary reference
|
|
33797
34456
|
* <static domain reference block>
|
|
33798
34457
|
*
|
|
34458
|
+
* ## Live fortress context ← WP-V1.3-9 Tau-3, when present
|
|
34459
|
+
* ### <Category>
|
|
34460
|
+
* <fetcher payload>
|
|
34461
|
+
*
|
|
33799
34462
|
* ## Prior conversation ← WP-V1.3-9 Tau-2, when present
|
|
33800
34463
|
* OPERATOR: ...
|
|
33801
34464
|
* CONCIERGE: ...
|
|
33802
|
-
* ---
|
|
33803
34465
|
*
|
|
33804
34466
|
* ## Recent activity
|
|
33805
34467
|
* <recentActivity output>
|
|
@@ -33818,13 +34480,14 @@ Note: this is a static reference block (v1.2.x). Dynamic context injection (live
|
|
|
33818
34480
|
* if available; the v1.2 selector does not expose one, so structured
|
|
33819
34481
|
* serialization is the canonical path for v1.3.
|
|
33820
34482
|
*/
|
|
33821
|
-
async assembleConciergeContext(priorTurns = []) {
|
|
34483
|
+
async assembleConciergeContext(priorTurns = [], dynamicSection = "") {
|
|
33822
34484
|
const ref = `## Sanctuary reference
|
|
33823
34485
|
${SANCTUARY_DOMAIN_REFERENCE}`;
|
|
33824
34486
|
const priorSection = this.formatPriorTurnsSection(priorTurns);
|
|
33825
34487
|
if (!this.contextProviders) {
|
|
33826
34488
|
return [
|
|
33827
34489
|
ref,
|
|
34490
|
+
...dynamicSection ? [dynamicSection] : [],
|
|
33828
34491
|
...priorSection ? [priorSection] : [],
|
|
33829
34492
|
"## Recent activity\n(no providers wired)",
|
|
33830
34493
|
"## Wrapped agents\n(no providers wired)",
|
|
@@ -33838,6 +34501,7 @@ ${SANCTUARY_DOMAIN_REFERENCE}`;
|
|
|
33838
34501
|
]);
|
|
33839
34502
|
return [
|
|
33840
34503
|
ref,
|
|
34504
|
+
...dynamicSection ? [dynamicSection] : [],
|
|
33841
34505
|
...priorSection ? [priorSection] : [],
|
|
33842
34506
|
`## Recent activity
|
|
33843
34507
|
${activity}`,
|
|
@@ -33847,6 +34511,51 @@ ${agents}`,
|
|
|
33847
34511
|
${inbox}`
|
|
33848
34512
|
].join("\n\n");
|
|
33849
34513
|
}
|
|
34514
|
+
/**
|
|
34515
|
+
* Run the WP-V1.3-9 Tau-3 dynamic-context fold for a single round-
|
|
34516
|
+
* trip. Fail-soft on every axis: missing fetchers short-circuit to
|
|
34517
|
+
* an empty fold, fetcher failures emit a per-category audit event
|
|
34518
|
+
* and are omitted from the rendered section, an LLM-assist failure
|
|
34519
|
+
* proceeds with no fold. Returns the rendered section + the list of
|
|
34520
|
+
* categories whose data made it into the section (used for the
|
|
34521
|
+
* round-trip audit emission).
|
|
34522
|
+
*/
|
|
34523
|
+
async runDynamicContextFold(query) {
|
|
34524
|
+
if (!this.contextFetchers) {
|
|
34525
|
+
return { section: "", categoriesIncluded: [] };
|
|
34526
|
+
}
|
|
34527
|
+
const result = await foldContext(query, this.contextFetchers, {
|
|
34528
|
+
maxTokens: this.dynamicContextBudget,
|
|
34529
|
+
...this.contextLlmAssist ? { llmAssistClassify: this.contextLlmAssist } : {},
|
|
34530
|
+
onFetcherFailure: (category, error) => {
|
|
34531
|
+
this.emitContextFetcherFailed(category, classifyFetcherError(error));
|
|
34532
|
+
}
|
|
34533
|
+
});
|
|
34534
|
+
return result;
|
|
34535
|
+
}
|
|
34536
|
+
/**
|
|
34537
|
+
* Emit the WP-V1.3-9 Tau-3 fetcher-failure audit event. Pulled out
|
|
34538
|
+
* of the fold path so the dynamic-context handler stays readable.
|
|
34539
|
+
* Emits with `result: "failure"` since the named category dropped
|
|
34540
|
+
* from the rendered section for this round-trip.
|
|
34541
|
+
*/
|
|
34542
|
+
emitContextFetcherFailed(category, failureReason) {
|
|
34543
|
+
const payload = {
|
|
34544
|
+
version: "1.2",
|
|
34545
|
+
event_id: makeEventId("conc-ctxfail"),
|
|
34546
|
+
emitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
34547
|
+
identity_id: this.identityId,
|
|
34548
|
+
kind: "operator_concierge_context_fetcher_failed",
|
|
34549
|
+
surface: "concierge",
|
|
34550
|
+
category,
|
|
34551
|
+
failure_reason: failureReason
|
|
34552
|
+
};
|
|
34553
|
+
this.emit(
|
|
34554
|
+
OPERATOR_CHAT_OPS.CONCIERGE_CONTEXT_FETCHER_FAILED,
|
|
34555
|
+
payload,
|
|
34556
|
+
"failure"
|
|
34557
|
+
);
|
|
34558
|
+
}
|
|
33850
34559
|
/**
|
|
33851
34560
|
* Render the prior-conversation section with token-budget enforcement
|
|
33852
34561
|
* (WP-V1.3-9 Tau-2). Drops oldest turns first when the rendered
|
|
@@ -33857,14 +34566,14 @@ ${inbox}`
|
|
|
33857
34566
|
if (turns.length === 0) return "";
|
|
33858
34567
|
const HEADER = "## Prior conversation";
|
|
33859
34568
|
const lines = turns.map(formatPriorTurnLine);
|
|
33860
|
-
const headerTokens =
|
|
34569
|
+
const headerTokens = approxTokenLen2(`${HEADER}
|
|
33861
34570
|
`);
|
|
33862
|
-
const sepTokens =
|
|
34571
|
+
const sepTokens = approxTokenLen2("\n");
|
|
33863
34572
|
let runningTokens = headerTokens;
|
|
33864
34573
|
let runningLines = [];
|
|
33865
34574
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
33866
34575
|
const line = lines[i];
|
|
33867
|
-
const tokens =
|
|
34576
|
+
const tokens = approxTokenLen2(line) + (runningLines.length > 0 ? sepTokens : 0);
|
|
33868
34577
|
if (runningTokens + tokens > this.historyTokenBudget) break;
|
|
33869
34578
|
runningTokens += tokens;
|
|
33870
34579
|
runningLines.push(line);
|
|
@@ -33892,7 +34601,7 @@ ${runningLines.join("\n")}`;
|
|
|
33892
34601
|
function chatStorageKey(surface, threadKey) {
|
|
33893
34602
|
return `${surface}.${threadKey}`;
|
|
33894
34603
|
}
|
|
33895
|
-
var OPERATOR_CHAT_NAMESPACE,
|
|
34604
|
+
var OPERATOR_CHAT_NAMESPACE, HKDF_INFO2, OperatorChatStore;
|
|
33896
34605
|
var init_operator_chat_store = __esm({
|
|
33897
34606
|
"src/chat/operator-chat-store.ts"() {
|
|
33898
34607
|
init_encryption();
|
|
@@ -33900,13 +34609,13 @@ var init_operator_chat_store = __esm({
|
|
|
33900
34609
|
init_encoding();
|
|
33901
34610
|
init_operator_chat_types();
|
|
33902
34611
|
OPERATOR_CHAT_NAMESPACE = "_chat";
|
|
33903
|
-
|
|
34612
|
+
HKDF_INFO2 = "operator-chat-store-v1";
|
|
33904
34613
|
OperatorChatStore = class {
|
|
33905
34614
|
storage;
|
|
33906
34615
|
encryptionKey;
|
|
33907
34616
|
constructor(storage, masterKey) {
|
|
33908
34617
|
this.storage = storage;
|
|
33909
|
-
this.encryptionKey = derivePurposeKey(masterKey,
|
|
34618
|
+
this.encryptionKey = derivePurposeKey(masterKey, HKDF_INFO2);
|
|
33910
34619
|
}
|
|
33911
34620
|
/**
|
|
33912
34621
|
* Load a thread. Returns null if no record exists or if the on-disk
|
|
@@ -33991,7 +34700,7 @@ var init_operator_chat_store = __esm({
|
|
|
33991
34700
|
function bundleKey(threadId) {
|
|
33992
34701
|
return `${CONCIERGE_MEMORY_KEY_PREFIX}${threadId}`;
|
|
33993
34702
|
}
|
|
33994
|
-
function
|
|
34703
|
+
function stripKeyPrefix2(key) {
|
|
33995
34704
|
if (!key.startsWith(CONCIERGE_MEMORY_KEY_PREFIX)) return null;
|
|
33996
34705
|
return key.slice(CONCIERGE_MEMORY_KEY_PREFIX.length);
|
|
33997
34706
|
}
|
|
@@ -34002,7 +34711,7 @@ function lastTurnId(bundle) {
|
|
|
34002
34711
|
}
|
|
34003
34712
|
return max;
|
|
34004
34713
|
}
|
|
34005
|
-
var CONCIERGE_MEMORY_NAMESPACE, CONCIERGE_MEMORY_KEY_PREFIX,
|
|
34714
|
+
var CONCIERGE_MEMORY_NAMESPACE, CONCIERGE_MEMORY_KEY_PREFIX, HKDF_INFO3, DEFAULT_CONCIERGE_RETENTION_DAYS, MAX_BUNDLE_BYTES3, ConciergeMemoryStore;
|
|
34006
34715
|
var init_concierge_memory_store = __esm({
|
|
34007
34716
|
"src/chat/concierge-memory-store.ts"() {
|
|
34008
34717
|
init_encryption();
|
|
@@ -34010,9 +34719,9 @@ var init_concierge_memory_store = __esm({
|
|
|
34010
34719
|
init_encoding();
|
|
34011
34720
|
CONCIERGE_MEMORY_NAMESPACE = "_chat";
|
|
34012
34721
|
CONCIERGE_MEMORY_KEY_PREFIX = "concierge_memory.";
|
|
34013
|
-
|
|
34722
|
+
HKDF_INFO3 = "concierge-memory-store-v1";
|
|
34014
34723
|
DEFAULT_CONCIERGE_RETENTION_DAYS = 30;
|
|
34015
|
-
|
|
34724
|
+
MAX_BUNDLE_BYTES3 = 4 * 1024 * 1024;
|
|
34016
34725
|
ConciergeMemoryStore = class {
|
|
34017
34726
|
storage;
|
|
34018
34727
|
encryptionKey;
|
|
@@ -34021,7 +34730,7 @@ var init_concierge_memory_store = __esm({
|
|
|
34021
34730
|
locks;
|
|
34022
34731
|
constructor(opts) {
|
|
34023
34732
|
this.storage = opts.storage;
|
|
34024
|
-
this.encryptionKey = derivePurposeKey(opts.masterKey,
|
|
34733
|
+
this.encryptionKey = derivePurposeKey(opts.masterKey, HKDF_INFO3);
|
|
34025
34734
|
this.fortressId = opts.fortressId;
|
|
34026
34735
|
this.retentionDays = opts.retentionDays !== void 0 && opts.retentionDays > 0 ? opts.retentionDays : DEFAULT_CONCIERGE_RETENTION_DAYS;
|
|
34027
34736
|
this.locks = /* @__PURE__ */ new Map();
|
|
@@ -34100,7 +34809,7 @@ var init_concierge_memory_store = __esm({
|
|
|
34100
34809
|
return { ok: false, reason: "io_failed" };
|
|
34101
34810
|
}
|
|
34102
34811
|
if (!raw) return { ok: true, turns: [] };
|
|
34103
|
-
if (raw.length >
|
|
34812
|
+
if (raw.length > MAX_BUNDLE_BYTES3) {
|
|
34104
34813
|
return { ok: false, reason: "oversize_bundle" };
|
|
34105
34814
|
}
|
|
34106
34815
|
let envelope;
|
|
@@ -34147,7 +34856,7 @@ var init_concierge_memory_store = __esm({
|
|
|
34147
34856
|
);
|
|
34148
34857
|
const summaries = [];
|
|
34149
34858
|
for (const meta of entries) {
|
|
34150
|
-
const threadId =
|
|
34859
|
+
const threadId = stripKeyPrefix2(meta.key);
|
|
34151
34860
|
if (threadId === null) continue;
|
|
34152
34861
|
const bundle = await this.loadBundle(threadId);
|
|
34153
34862
|
if (!bundle || bundle.turns.length === 0) continue;
|
|
@@ -34200,7 +34909,7 @@ var init_concierge_memory_store = __esm({
|
|
|
34200
34909
|
);
|
|
34201
34910
|
let pruned = 0;
|
|
34202
34911
|
for (const meta of entries) {
|
|
34203
|
-
const threadId =
|
|
34912
|
+
const threadId = stripKeyPrefix2(meta.key);
|
|
34204
34913
|
if (threadId === null) continue;
|
|
34205
34914
|
pruned += await this.withLock(threadId, async () => {
|
|
34206
34915
|
const bundle = await this.loadBundle(threadId);
|
|
@@ -34231,7 +34940,7 @@ var init_concierge_memory_store = __esm({
|
|
|
34231
34940
|
return null;
|
|
34232
34941
|
}
|
|
34233
34942
|
if (!raw) return null;
|
|
34234
|
-
if (raw.length >
|
|
34943
|
+
if (raw.length > MAX_BUNDLE_BYTES3) return null;
|
|
34235
34944
|
try {
|
|
34236
34945
|
const envelope = JSON.parse(bytesToString(raw));
|
|
34237
34946
|
const aad = stringToBytes(threadId);
|
|
@@ -34322,7 +35031,18 @@ function buildV11Bindings(inputs) {
|
|
|
34322
35031
|
registry
|
|
34323
35032
|
}),
|
|
34324
35033
|
conciergePiiFilter: buildConciergePiiFilter(),
|
|
34325
|
-
conciergeMemory
|
|
35034
|
+
conciergeMemory,
|
|
35035
|
+
conciergeContextFetchers: buildConciergeContextFetchers({
|
|
35036
|
+
auditLog: inputs.auditLog,
|
|
35037
|
+
identityId: inputs.identityId,
|
|
35038
|
+
registry
|
|
35039
|
+
}),
|
|
35040
|
+
...inputs.intelligenceSelector ? {
|
|
35041
|
+
conciergeContextLlmAssist: buildConciergeContextLlmAssist({
|
|
35042
|
+
selector: inputs.intelligenceSelector,
|
|
35043
|
+
identityId: inputs.identityId
|
|
35044
|
+
})
|
|
35045
|
+
} : {}
|
|
34326
35046
|
});
|
|
34327
35047
|
}
|
|
34328
35048
|
const hubService = new HubService({
|
|
@@ -34383,6 +35103,107 @@ function buildConciergeContextProviders(args) {
|
|
|
34383
35103
|
}
|
|
34384
35104
|
};
|
|
34385
35105
|
}
|
|
35106
|
+
function buildConciergeContextFetchers(args) {
|
|
35107
|
+
const empty = async () => "";
|
|
35108
|
+
return {
|
|
35109
|
+
templates: async () => {
|
|
35110
|
+
const entries = listTemplates();
|
|
35111
|
+
if (entries.length === 0) return "(no templates installed)";
|
|
35112
|
+
const lines = entries.map((e) => {
|
|
35113
|
+
const m = e.metadata;
|
|
35114
|
+
return `${m.name} (tier ${m.tier}, channel ${m.channel}, target ${m.target_archetype})`;
|
|
35115
|
+
});
|
|
35116
|
+
return lines.join("\n");
|
|
35117
|
+
},
|
|
35118
|
+
agent_state: async (agentNameHint) => {
|
|
35119
|
+
const records = args.registry.list({ identity_id: args.identityId });
|
|
35120
|
+
if (records.length === 0) return "(no wrapped agents)";
|
|
35121
|
+
const filtered = agentNameHint ? records.filter(
|
|
35122
|
+
(r) => r.agent_id.toLowerCase().includes(agentNameHint.toLowerCase()) || r.harness.toLowerCase().includes(agentNameHint.toLowerCase())
|
|
35123
|
+
) : records;
|
|
35124
|
+
const target = filtered.length > 0 ? filtered : records;
|
|
35125
|
+
const lines = target.slice(0, 20).map((r) => {
|
|
35126
|
+
const tmpl = typeof r.channel_template_id === "string" ? r.channel_template_id : "no_template";
|
|
35127
|
+
return `${r.agent_id} harness=${r.harness} status=${r.status} template=${tmpl}`;
|
|
35128
|
+
});
|
|
35129
|
+
return lines.join("\n");
|
|
35130
|
+
},
|
|
35131
|
+
agent_activity: async (agentNameHint) => {
|
|
35132
|
+
const result = await args.auditLog.query({ limit: 50 });
|
|
35133
|
+
const owned = result.entries.filter(
|
|
35134
|
+
(e) => e.identity_id === args.identityId
|
|
35135
|
+
);
|
|
35136
|
+
const filtered = agentNameHint ? owned.filter((e) => {
|
|
35137
|
+
const agentId = e.details && typeof e.details["agent_id"] === "string" ? e.details["agent_id"] : "";
|
|
35138
|
+
return agentId.toLowerCase().includes(agentNameHint.toLowerCase());
|
|
35139
|
+
}) : owned;
|
|
35140
|
+
const tail = (filtered.length > 0 ? filtered : owned).slice(-20);
|
|
35141
|
+
if (tail.length === 0) return "(no activity)";
|
|
35142
|
+
return tail.map((e) => {
|
|
35143
|
+
const agentId = (e.details && typeof e.details["agent_id"] === "string" ? e.details["agent_id"] : null) ?? "_fortress";
|
|
35144
|
+
return `${e.timestamp} ${e.layer}.${e.operation} agent=${agentId} result=${e.result}`;
|
|
35145
|
+
}).join("\n");
|
|
35146
|
+
},
|
|
35147
|
+
audit_log: async () => {
|
|
35148
|
+
const result = await args.auditLog.query({ limit: 30 });
|
|
35149
|
+
const owned = result.entries.filter(
|
|
35150
|
+
(e) => e.identity_id === args.identityId
|
|
35151
|
+
);
|
|
35152
|
+
if (owned.length === 0) return "(no audit log entries)";
|
|
35153
|
+
return owned.slice(-30).map(
|
|
35154
|
+
(e) => `${e.timestamp} ${e.layer}.${e.operation} result=${e.result}`
|
|
35155
|
+
).join("\n");
|
|
35156
|
+
},
|
|
35157
|
+
sentinel_findings: empty,
|
|
35158
|
+
anomaly_alerts: empty,
|
|
35159
|
+
recent_receipts: async () => {
|
|
35160
|
+
const result = await args.auditLog.query({ limit: 100 });
|
|
35161
|
+
const owned = result.entries.filter(
|
|
35162
|
+
(e) => e.identity_id === args.identityId && e.operation.startsWith("composition_")
|
|
35163
|
+
);
|
|
35164
|
+
if (owned.length === 0) return "(no recent composition events)";
|
|
35165
|
+
return owned.slice(-15).map((e) => `${e.timestamp} ${e.operation} result=${e.result}`).join("\n");
|
|
35166
|
+
},
|
|
35167
|
+
verascore_deltas: empty
|
|
35168
|
+
};
|
|
35169
|
+
}
|
|
35170
|
+
function buildConciergeContextLlmAssist(args) {
|
|
35171
|
+
return async (query, categories) => {
|
|
35172
|
+
const labelList = categories.map((c) => `- ${c}`).join("\n");
|
|
35173
|
+
const prompt2 = `You are a router. Classify the operator's query into one of the categories below or "none".
|
|
35174
|
+
Reply with exactly one token: one category name or "none".
|
|
35175
|
+
|
|
35176
|
+
Categories:
|
|
35177
|
+
${labelList}
|
|
35178
|
+
|
|
35179
|
+
Query: ${query}
|
|
35180
|
+
|
|
35181
|
+
Category:`;
|
|
35182
|
+
try {
|
|
35183
|
+
const handle = await args.selector.getSubstrate("concierge");
|
|
35184
|
+
if (!handle.capability.summarize) return "none";
|
|
35185
|
+
const response = await args.selector.invokeSummarize("concierge", {
|
|
35186
|
+
kind: "summarize",
|
|
35187
|
+
context: prompt2,
|
|
35188
|
+
query: "Output the single category token.",
|
|
35189
|
+
maxTokens: 16
|
|
35190
|
+
});
|
|
35191
|
+
if (response.failureClass || response.body.kind !== "summarize") {
|
|
35192
|
+
return "none";
|
|
35193
|
+
}
|
|
35194
|
+
const raw = response.body.text.trim().toLowerCase();
|
|
35195
|
+
const head = raw.split(/\s|[.,!?:;]/)[0] ?? "";
|
|
35196
|
+
const normalized = head.replace(/[^a-z_]/g, "");
|
|
35197
|
+
const known = categories;
|
|
35198
|
+
if (known.includes(normalized)) {
|
|
35199
|
+
return normalized;
|
|
35200
|
+
}
|
|
35201
|
+
return "none";
|
|
35202
|
+
} catch {
|
|
35203
|
+
return "none";
|
|
35204
|
+
}
|
|
35205
|
+
};
|
|
35206
|
+
}
|
|
34386
35207
|
function buildConciergePiiFilter() {
|
|
34387
35208
|
return {
|
|
34388
35209
|
filter(input) {
|
|
@@ -34410,6 +35231,7 @@ var init_wiring = __esm({
|
|
|
34410
35231
|
init_agent_registry_persistence();
|
|
34411
35232
|
init_operator_chat_index();
|
|
34412
35233
|
init_privacy_filter();
|
|
35234
|
+
init_registry();
|
|
34413
35235
|
CapabilityErrorAgentController = class {
|
|
34414
35236
|
fail(action) {
|
|
34415
35237
|
throw new HubCapabilityError(
|
|
@@ -34557,7 +35379,7 @@ var init_defaults = __esm({
|
|
|
34557
35379
|
});
|
|
34558
35380
|
|
|
34559
35381
|
// src/intelligence/policy-store.ts
|
|
34560
|
-
var INTELLIGENCE_NAMESPACE, SUBSTRATE_CONFIG_KEY,
|
|
35382
|
+
var INTELLIGENCE_NAMESPACE, SUBSTRATE_CONFIG_KEY, HKDF_INFO4, IntelligenceConfigStore;
|
|
34561
35383
|
var init_policy_store = __esm({
|
|
34562
35384
|
"src/intelligence/policy-store.ts"() {
|
|
34563
35385
|
init_encryption();
|
|
@@ -34566,13 +35388,13 @@ var init_policy_store = __esm({
|
|
|
34566
35388
|
init_defaults();
|
|
34567
35389
|
INTELLIGENCE_NAMESPACE = "_intelligence";
|
|
34568
35390
|
SUBSTRATE_CONFIG_KEY = "substrate-config";
|
|
34569
|
-
|
|
35391
|
+
HKDF_INFO4 = "intelligence-substrate-config";
|
|
34570
35392
|
IntelligenceConfigStore = class {
|
|
34571
35393
|
storage;
|
|
34572
35394
|
encryptionKey;
|
|
34573
35395
|
constructor(storage, masterKey) {
|
|
34574
35396
|
this.storage = storage;
|
|
34575
|
-
this.encryptionKey = derivePurposeKey(masterKey,
|
|
35397
|
+
this.encryptionKey = derivePurposeKey(masterKey, HKDF_INFO4);
|
|
34576
35398
|
}
|
|
34577
35399
|
/**
|
|
34578
35400
|
* Load the operator's substrate config from disk. Returns the config
|
|
@@ -38490,12 +39312,18 @@ ${err.message}
|
|
|
38490
39312
|
} : void 0;
|
|
38491
39313
|
const fortressIdForAggregator = fortressIdFromStoragePath(config.storage_path);
|
|
38492
39314
|
const aggregatorIdentityId = identityManager.getPrimaryIdentityId() ?? `fortress:${config.storage_path}`;
|
|
39315
|
+
const aggregatorPayloadStore = new AggregatorPayloadStore({
|
|
39316
|
+
storage,
|
|
39317
|
+
masterKey,
|
|
39318
|
+
fortressId: fortressIdForAggregator
|
|
39319
|
+
});
|
|
38493
39320
|
const approvalAggregator = new ApprovalAggregator({
|
|
38494
39321
|
storage,
|
|
38495
39322
|
masterKey,
|
|
38496
39323
|
auditLog,
|
|
38497
39324
|
identityId: aggregatorIdentityId,
|
|
38498
|
-
fortressId: fortressIdForAggregator
|
|
39325
|
+
fortressId: fortressIdForAggregator,
|
|
39326
|
+
payloadStore: aggregatorPayloadStore
|
|
38499
39327
|
});
|
|
38500
39328
|
const wrappedApprovalChannel = new AggregatorBackedChannel({
|
|
38501
39329
|
underlying: approvalChannel,
|
|
@@ -38709,6 +39537,7 @@ var init_src = __esm({
|
|
|
38709
39537
|
init_gate();
|
|
38710
39538
|
init_approval_aggregator();
|
|
38711
39539
|
init_aggregator_backed_channel();
|
|
39540
|
+
init_aggregator_store();
|
|
38712
39541
|
init_tools4();
|
|
38713
39542
|
init_router();
|
|
38714
39543
|
init_router();
|