@t2000/engine 1.10.1 → 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -279,6 +279,18 @@ declare class BalanceTracker {
279
279
  private lastBalanceAt;
280
280
  private lastWriteAt;
281
281
  recordRead(): void;
282
+ /**
283
+ * [v1.11 F2] Seed `lastBalanceAt` from an external snapshot timestamp.
284
+ * Used by the engine constructor when the host passes
285
+ * `EngineConfig.financialContextSeed.balanceAt` — i.e. the system
286
+ * prompt already embeds a fresh balance snapshot from that time so
287
+ * the LLM has authoritative balance data without the host
288
+ * round-tripping a `balance_check` tool call first. Pre-fix the
289
+ * `Balance has not been checked this session` hint fired on every
290
+ * first-turn write, even when audric had just embedded the daily
291
+ * `<financial_context>` block — pure noise for the LLM and the user.
292
+ */
293
+ recordReadAt(at: number): void;
282
294
  recordWrite(): void;
283
295
  isStale(): boolean;
284
296
  hasEverRead(): boolean;
@@ -1311,6 +1323,45 @@ interface EngineConfig {
1311
1323
  usdValue: number;
1312
1324
  walletAddress?: string;
1313
1325
  }) => void | Promise<void>;
1326
+ /**
1327
+ * [v1.11 F2] Trust signal from the host: the system prompt already
1328
+ * embeds a fresh financial-context snapshot covering balance + HF as
1329
+ * of `balanceAt` (Unix ms). Pre-seeds the guard runner so the
1330
+ * "Balance has not been checked this session" / "Health factor has
1331
+ * not been checked this session" hints DON'T fire on the first turn.
1332
+ *
1333
+ * Pre-v1.11 the guards started cold every chat: the LLM saw the
1334
+ * `<financial_context>` block in the system prompt (with balances +
1335
+ * HF baked in) but the BalanceTracker still reported `hasEverRead()`
1336
+ * = false, so every first-turn write got pinged with a redundant
1337
+ * "call balance_check first" hint. Audric's UC1/UC2/UC3 P2.6 runs
1338
+ * showed the noise verbatim ("Balance not checked this session"
1339
+ * appeared on every first-turn permission card).
1340
+ *
1341
+ * Why a host-supplied seed (vs. engine sniffing the system prompt):
1342
+ * the engine doesn't own the prompt format. Audric builds
1343
+ * `<financial_context>` from `UserFinancialContext`; another host
1344
+ * may not (Audric CLI, server-signed automations). Having the host
1345
+ * pass an explicit seed keeps the engine prompt-agnostic.
1346
+ *
1347
+ * Stale snapshots (>30min old): still seed. The LLM can judge
1348
+ * whether to call `balance_check` for a fresh value based on the
1349
+ * snapshot timestamp surfaced inside the financial-context block;
1350
+ * the guard's job is to prevent unprompted writes against
1351
+ * unknown-state, NOT to enforce a freshness SLA.
1352
+ */
1353
+ financialContextSeed?: {
1354
+ /** Unix ms timestamp of the snapshot. Any non-zero value seeds `lastBalanceAt`. */
1355
+ balanceAt?: number;
1356
+ /**
1357
+ * Health factor at snapshot time. Pass `null` if the user has no
1358
+ * debt (HF undefined / Infinity in audric — render the snapshot
1359
+ * row as "no debt" and don't seed). Pass a number to skip the
1360
+ * "Health factor has not been checked this session" hint on
1361
+ * first-turn write.
1362
+ */
1363
+ healthFactor?: number | null;
1364
+ };
1314
1365
  /**
1315
1366
  * [v1.4 Item 4] Per-guard observation hook. Forwarded to `runGuards`
1316
1367
  * and fired once per non-`pass` verdict so hosts can record guard
package/dist/index.js CHANGED
@@ -5575,6 +5575,22 @@ var BalanceTracker = class {
5575
5575
  recordRead() {
5576
5576
  this.lastBalanceAt = Date.now();
5577
5577
  }
5578
+ /**
5579
+ * [v1.11 F2] Seed `lastBalanceAt` from an external snapshot timestamp.
5580
+ * Used by the engine constructor when the host passes
5581
+ * `EngineConfig.financialContextSeed.balanceAt` — i.e. the system
5582
+ * prompt already embeds a fresh balance snapshot from that time so
5583
+ * the LLM has authoritative balance data without the host
5584
+ * round-tripping a `balance_check` tool call first. Pre-fix the
5585
+ * `Balance has not been checked this session` hint fired on every
5586
+ * first-turn write, even when audric had just embedded the daily
5587
+ * `<financial_context>` block — pure noise for the LLM and the user.
5588
+ */
5589
+ recordReadAt(at) {
5590
+ if (at > this.lastBalanceAt) {
5591
+ this.lastBalanceAt = at;
5592
+ }
5593
+ }
5578
5594
  recordWrite() {
5579
5595
  this.lastWriteAt = Date.now();
5580
5596
  }
@@ -6832,6 +6848,15 @@ var QueryEngine = class {
6832
6848
  this.costTracker = new CostTracker(config.costTracker);
6833
6849
  this.guardConfig = config.guards;
6834
6850
  this.guardState = createGuardRunnerState();
6851
+ if (config.financialContextSeed) {
6852
+ const { balanceAt, healthFactor } = config.financialContextSeed;
6853
+ if (typeof balanceAt === "number" && balanceAt > 0) {
6854
+ this.guardState.balanceTracker.recordReadAt(balanceAt);
6855
+ }
6856
+ if (typeof healthFactor === "number") {
6857
+ this.guardState.lastHealthFactor = healthFactor;
6858
+ }
6859
+ }
6835
6860
  this.recipes = config.recipes;
6836
6861
  this.contextBudget = new ContextBudget(config.contextBudget);
6837
6862
  this.contextSummarizer = config.contextSummarizer;