@cueai/omni-reader-mcp 1.6.0 → 1.7.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.
@@ -47,6 +47,11 @@ const PERSISTED_V4_KEYS = [
47
47
  ...PERSISTED_V3_KEYS,
48
48
  "result_delivery_effective",
49
49
  ];
50
+ const PERSISTED_V5_KEYS = [
51
+ ...PERSISTED_V4_KEYS,
52
+ "direct_profile",
53
+ "billing",
54
+ ];
50
55
  const JOURNAL_STATES = new Set([
51
56
  "CREATED",
52
57
  "GRANT_PENDING",
@@ -280,6 +285,53 @@ function parseVersionFourRecord(value) {
280
285
  result_delivery_effective: result_delivery_effective,
281
286
  };
282
287
  }
288
+ function isBillingDirectProfile(value) {
289
+ return value === "omni.direct_text_billing.v1"
290
+ || value === "omni.direct_grounding_billing.v1";
291
+ }
292
+ function isPersistedBilling(value) {
293
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
294
+ return false;
295
+ }
296
+ const billing = value;
297
+ return Object.keys(billing).length === 2
298
+ && "credits_charged" in billing
299
+ && "credits_remaining" in billing
300
+ && typeof billing.credits_charged === "number"
301
+ && Number.isFinite(billing.credits_charged)
302
+ && billing.credits_charged >= 0
303
+ && typeof billing.credits_remaining === "number"
304
+ && Number.isFinite(billing.credits_remaining)
305
+ && billing.credits_remaining >= 0;
306
+ }
307
+ function parseVersionFiveRecord(value) {
308
+ const keys = Object.keys(value);
309
+ if (keys.length !== PERSISTED_V5_KEYS.length
310
+ || PERSISTED_V5_KEYS.some((key) => !(key in value))
311
+ || value.version !== 5
312
+ || !(value.direct_profile === null
313
+ || isBillingDirectProfile(value.direct_profile))
314
+ || !(value.billing === null || isPersistedBilling(value.billing))) {
315
+ throw new Error("version-5 record fields are invalid");
316
+ }
317
+ const { direct_profile, billing, ...versionFourFields } = value;
318
+ const validated = parseVersionFourRecord({
319
+ ...versionFourFields,
320
+ version: 4,
321
+ });
322
+ if ((validated.sourceKind === "url" && direct_profile !== null)
323
+ || (validated.sourceKind === "local"
324
+ && billing !== null
325
+ && direct_profile === null)) {
326
+ throw new Error("version-5 settlement facts are invalid");
327
+ }
328
+ return {
329
+ ...validated,
330
+ version: 5,
331
+ direct_profile: direct_profile,
332
+ billing: billing,
333
+ };
334
+ }
283
335
  function parsePersistedRecord(value) {
284
336
  if (value === null || typeof value !== "object" || Array.isArray(value)) {
285
337
  throw new Error("record is not an object");
@@ -293,12 +345,14 @@ function parsePersistedRecord(value) {
293
345
  return parseVersionThreeRecord(record);
294
346
  if (record.version === 4)
295
347
  return parseVersionFourRecord(record);
348
+ if (record.version === 5)
349
+ return parseVersionFiveRecord(record);
296
350
  throw new Error("record version is invalid");
297
351
  }
298
352
  function migrateInMemory(stored) {
299
- if (stored.version === 3 || stored.version === 4) {
353
+ if (stored.version === 3 || stored.version === 4 || stored.version === 5) {
300
354
  return {
301
- version: 4,
355
+ version: 5,
302
356
  clientRequestId: stored.clientRequestId,
303
357
  requestIdentityHmac: stored.requestIdentityHmac,
304
358
  sourceLocatorHmac: stored.sourceLocatorHmac,
@@ -309,9 +363,16 @@ function migrateInMemory(stored) {
309
363
  detail: stored.detail,
310
364
  groundingSchemaVersion: stored.groundingSchemaVersion,
311
365
  bundleProtocolVersion: stored.bundleProtocolVersion,
312
- resultDeliveryEffective: stored.version === 4
366
+ resultDeliveryEffective: stored.version === 4 || stored.version === 5
313
367
  ? stored.result_delivery_effective
314
368
  : "auto",
369
+ directProfile: stored.version === 5 ? stored.direct_profile : null,
370
+ billing: stored.version === 5 && stored.billing !== null
371
+ ? {
372
+ creditsCharged: stored.billing.credits_charged,
373
+ creditsRemaining: stored.billing.credits_remaining,
374
+ }
375
+ : null,
315
376
  operationId: stored.operationId,
316
377
  operationToken: stored.operationToken,
317
378
  state: stored.state,
@@ -338,7 +399,7 @@ function migrateInMemory(stored) {
338
399
  // are recomputed only when safe canonical source facts reconstruct the
339
400
  // stored unkeyed requestHash (see #reconstructLegacy).
340
401
  return {
341
- version: 4,
402
+ version: 5,
342
403
  clientRequestId: stored.clientRequestId,
343
404
  requestIdentityHmac: null,
344
405
  sourceLocatorHmac: null,
@@ -350,6 +411,8 @@ function migrateInMemory(stored) {
350
411
  groundingSchemaVersion: "none",
351
412
  bundleProtocolVersion: "none",
352
413
  resultDeliveryEffective: "auto",
414
+ directProfile: null,
415
+ billing: null,
353
416
  operationId: stored.operationId,
354
417
  operationToken: stored.operationToken,
355
418
  state: stored.state,
@@ -372,7 +435,7 @@ function migrateInMemory(stored) {
372
435
  };
373
436
  }
374
437
  return {
375
- version: 4,
438
+ version: 5,
376
439
  clientRequestId: stored.clientRequestId,
377
440
  requestIdentityHmac: null,
378
441
  sourceLocatorHmac: null,
@@ -384,6 +447,8 @@ function migrateInMemory(stored) {
384
447
  groundingSchemaVersion: "none",
385
448
  bundleProtocolVersion: "none",
386
449
  resultDeliveryEffective: "auto",
450
+ directProfile: null,
451
+ billing: null,
387
452
  operationId: stored.operationId,
388
453
  operationToken: stored.operationToken,
389
454
  state: stored.state,
@@ -439,6 +504,10 @@ function assertStableTransition(current, updated) {
439
504
  throw bridgeError("JOURNAL_IDENTITY_CONFLICT", "A stable local operation identifier cannot be replaced.", false);
440
505
  }
441
506
  }
507
+ if (current.directProfile !== null
508
+ && current.directProfile !== updated.directProfile) {
509
+ throw bridgeError("JOURNAL_DIRECT_PROFILE_MISMATCH", "The direct billing profile cannot be replaced.", false);
510
+ }
442
511
  if (current.operationToken !== null &&
443
512
  current.operationToken !== updated.operationToken &&
444
513
  !(updated.operationToken === null && TERMINAL_STATES.has(updated.state))) {
@@ -470,6 +539,18 @@ function hmacEqual(left, right) {
470
539
  return false;
471
540
  return timingSafeEqual(Buffer.from(left, "hex"), Buffer.from(right, "hex"));
472
541
  }
542
+ function assertJournalBilling(billing) {
543
+ if (!Number.isFinite(billing.creditsCharged)
544
+ || billing.creditsCharged < 0
545
+ || !Number.isFinite(billing.creditsRemaining)
546
+ || billing.creditsRemaining < 0) {
547
+ throw bridgeError("JOURNAL_BILLING_INVALID", "The authoritative billing facts are invalid.", false);
548
+ }
549
+ }
550
+ function billingEqual(left, right) {
551
+ return left.creditsCharged === right.creditsCharged
552
+ && left.creditsRemaining === right.creditsRemaining;
553
+ }
473
554
  export class OperationJournal {
474
555
  #rootDirectory;
475
556
  #now;
@@ -487,7 +568,7 @@ export class OperationJournal {
487
568
  async sourceLocatorHmac(sourceLocator) {
488
569
  return this.#hmac(SOURCE_LOCATOR_DOMAIN, sourceLocator);
489
570
  }
490
- // v4 intent creation. canonicalIdentityJson is the exact canonical
571
+ // v5 intent creation. canonicalIdentityJson is the exact canonical
491
572
  // serialization of {source_kind, source_facts} (which includes the
492
573
  // normalized representation tuple); the journal derives the keyed identity
493
574
  // from it and persists only the HMAC, never the payload or any unkeyed hash.
@@ -502,7 +583,7 @@ export class OperationJournal {
502
583
  }
503
584
  const createdAt = this.#now().toISOString();
504
585
  const created = {
505
- version: 4,
586
+ version: 5,
506
587
  clientRequestId,
507
588
  requestIdentityHmac: await this.#hmac(REQUEST_IDENTITY_DOMAIN, canonicalIdentityJson),
508
589
  sourceLocatorHmac: sourceLocator === null
@@ -516,6 +597,8 @@ export class OperationJournal {
516
597
  groundingSchemaVersion: representation.groundingSchemaVersion,
517
598
  bundleProtocolVersion: representation.bundleProtocolVersion,
518
599
  resultDeliveryEffective: resultDelivery,
600
+ directProfile: null,
601
+ billing: null,
519
602
  operationId: null,
520
603
  operationToken: null,
521
604
  state: "CREATED",
@@ -555,7 +638,7 @@ export class OperationJournal {
555
638
  const stored = await this.#readRecord(clientRequestId);
556
639
  if (stored === null)
557
640
  return null;
558
- if (stored.version === 3 || stored.version === 4) {
641
+ if (stored.version === 3 || stored.version === 4 || stored.version === 5) {
559
642
  return this.#recordToPublic(clientRequestId, stored);
560
643
  }
561
644
  const expected = `sha256:${createHash("sha256").update(canonicalIdentityJson, "utf8").digest("hex")}`;
@@ -625,6 +708,80 @@ export class OperationJournal {
625
708
  return updated;
626
709
  });
627
710
  }
711
+ async bindDirectProfile(clientRequestId, directProfile) {
712
+ validateClientRequestId(clientRequestId);
713
+ if (!isBillingDirectProfile(directProfile)) {
714
+ throw bridgeError("JOURNAL_DIRECT_PROFILE_MISMATCH", "The direct billing profile does not match the operation source.", false);
715
+ }
716
+ return this.#withRecordLock(clientRequestId, async () => {
717
+ const stored = await this.#readRecord(clientRequestId);
718
+ if (stored === null) {
719
+ throw bridgeError("JOURNAL_RECORD_NOT_FOUND", "The local operation journal record is missing.", true);
720
+ }
721
+ const current = await this.#recordToPublic(clientRequestId, stored);
722
+ if (current.sourceKind !== "local") {
723
+ throw bridgeError("JOURNAL_DIRECT_PROFILE_MISMATCH", "The direct billing profile does not match the operation source.", false);
724
+ }
725
+ if (current.directProfile !== null) {
726
+ if (current.directProfile !== directProfile) {
727
+ throw bridgeError("JOURNAL_DIRECT_PROFILE_MISMATCH", "The direct billing profile cannot be replaced.", false);
728
+ }
729
+ return current;
730
+ }
731
+ const updated = {
732
+ ...current,
733
+ directProfile,
734
+ updatedAt: this.#now().toISOString(),
735
+ };
736
+ assertStableTransition(current, updated);
737
+ await this.#replaceRecord(await this.#persistedRecord(updated), this.#recordPath(clientRequestId));
738
+ await unlink(this.#legacyIssuedRecordPath(clientRequestId)).catch(() => undefined);
739
+ return updated;
740
+ });
741
+ }
742
+ async bindSettlementFacts(clientRequestId, facts) {
743
+ validateClientRequestId(clientRequestId);
744
+ assertJournalBilling(facts.billing);
745
+ return this.#withRecordLock(clientRequestId, async () => {
746
+ const stored = await this.#readRecord(clientRequestId);
747
+ if (stored === null) {
748
+ throw bridgeError("JOURNAL_RECORD_NOT_FOUND", "The local operation journal record is missing.", true);
749
+ }
750
+ const current = await this.#recordToPublic(clientRequestId, stored);
751
+ const profileMatchesSource = current.sourceKind === "url"
752
+ ? facts.directProfile === null
753
+ : isBillingDirectProfile(facts.directProfile);
754
+ if (!profileMatchesSource) {
755
+ throw bridgeError("JOURNAL_DIRECT_PROFILE_MISMATCH", "The direct billing profile does not match the operation source.", false);
756
+ }
757
+ if (current.billing !== null) {
758
+ if (current.directProfile !== facts.directProfile) {
759
+ throw bridgeError("JOURNAL_DIRECT_PROFILE_MISMATCH", "The direct billing profile cannot be replaced.", false);
760
+ }
761
+ if (!billingEqual(current.billing, facts.billing)) {
762
+ throw bridgeError("JOURNAL_BILLING_MISMATCH", "The authoritative billing facts cannot be replaced.", false);
763
+ }
764
+ return current;
765
+ }
766
+ if (current.directProfile !== null
767
+ && current.directProfile !== facts.directProfile) {
768
+ throw bridgeError("JOURNAL_DIRECT_PROFILE_MISMATCH", "The direct billing profile cannot be replaced.", false);
769
+ }
770
+ const updated = {
771
+ ...current,
772
+ directProfile: facts.directProfile,
773
+ billing: {
774
+ creditsCharged: facts.billing.creditsCharged,
775
+ creditsRemaining: facts.billing.creditsRemaining,
776
+ },
777
+ updatedAt: this.#now().toISOString(),
778
+ };
779
+ assertStableTransition(current, updated);
780
+ await this.#replaceRecord(await this.#persistedRecord(updated), this.#recordPath(clientRequestId));
781
+ await unlink(this.#legacyIssuedRecordPath(clientRequestId)).catch(() => undefined);
782
+ return updated;
783
+ });
784
+ }
628
785
  async loadByRequestId(clientRequestId) {
629
786
  validateClientRequestId(clientRequestId);
630
787
  const persisted = await this.#readRecord(clientRequestId);
@@ -658,7 +815,7 @@ export class OperationJournal {
658
815
  // the journal receives, so the keyed handle is derived over that value.
659
816
  const createdAt = this.#now().toISOString();
660
817
  const created = {
661
- version: 4,
818
+ version: 5,
662
819
  clientRequestId,
663
820
  requestIdentityHmac: await this.#hmac(REQUEST_IDENTITY_DOMAIN, requestHash),
664
821
  sourceLocatorHmac: null,
@@ -670,6 +827,8 @@ export class OperationJournal {
670
827
  groundingSchemaVersion: "none",
671
828
  bundleProtocolVersion: "none",
672
829
  resultDeliveryEffective: "auto",
830
+ directProfile: null,
831
+ billing: null,
673
832
  operationId: null,
674
833
  operationToken: null,
675
834
  state: "CREATED",
@@ -765,7 +924,7 @@ export class OperationJournal {
765
924
  }
766
925
  async #persistedRecord(record) {
767
926
  return {
768
- version: 4,
927
+ version: 5,
769
928
  clientRequestId: record.clientRequestId,
770
929
  // A legacy record persisted before reconstruction (for example a
771
930
  // source-free recovery failure) gets the deterministic keyed handle of
@@ -779,6 +938,13 @@ export class OperationJournal {
779
938
  groundingSchemaVersion: record.groundingSchemaVersion,
780
939
  bundleProtocolVersion: record.bundleProtocolVersion,
781
940
  result_delivery_effective: record.resultDeliveryEffective,
941
+ direct_profile: record.directProfile,
942
+ billing: record.billing === null
943
+ ? null
944
+ : {
945
+ credits_charged: record.billing.creditsCharged,
946
+ credits_remaining: record.billing.creditsRemaining,
947
+ },
782
948
  operationId: record.operationId,
783
949
  operationToken: record.operationToken === null
784
950
  ? null
@@ -804,7 +970,7 @@ export class OperationJournal {
804
970
  }
805
971
  async #persistedFromInMemory(record) {
806
972
  return {
807
- version: 4,
973
+ version: 5,
808
974
  clientRequestId: record.clientRequestId,
809
975
  requestIdentityHmac: record.requestIdentityHmac === null
810
976
  ? await this.#hmac(REQUEST_IDENTITY_DOMAIN, "")
@@ -815,6 +981,13 @@ export class OperationJournal {
815
981
  groundingSchemaVersion: record.groundingSchemaVersion,
816
982
  bundleProtocolVersion: record.bundleProtocolVersion,
817
983
  result_delivery_effective: record.resultDeliveryEffective,
984
+ direct_profile: record.directProfile,
985
+ billing: record.billing === null
986
+ ? null
987
+ : {
988
+ credits_charged: record.billing.creditsCharged,
989
+ credits_remaining: record.billing.creditsRemaining,
990
+ },
818
991
  operationId: record.operationId,
819
992
  operationToken: record.operationToken,
820
993
  state: record.state,
@@ -854,6 +1027,8 @@ export class OperationJournal {
854
1027
  groundingSchemaVersion: migrated.groundingSchemaVersion,
855
1028
  bundleProtocolVersion: migrated.bundleProtocolVersion,
856
1029
  resultDeliveryEffective: migrated.resultDeliveryEffective,
1030
+ directProfile: migrated.directProfile,
1031
+ billing: migrated.billing,
857
1032
  operationId: migrated.operationId,
858
1033
  operationToken,
859
1034
  uploadUrl: migrated.uploadUrl,
@@ -889,7 +1064,7 @@ export class OperationJournal {
889
1064
  return migrated;
890
1065
  }
891
1066
  async #requireMatchingRequest(clientRequestId, canonicalIdentityJson, sourceLocator, persisted) {
892
- if (persisted.version === 3 || persisted.version === 4) {
1067
+ if (persisted.version === 3 || persisted.version === 4 || persisted.version === 5) {
893
1068
  const expected = await this.#hmacExisting(REQUEST_IDENTITY_DOMAIN, canonicalIdentityJson);
894
1069
  if (!hmacEqual(persisted.requestIdentityHmac, expected)) {
895
1070
  throw bridgeError("IDEMPOTENCY_COLLISION", "This local operation request identifier is already bound to different metadata.", false);
@@ -903,7 +1078,7 @@ export class OperationJournal {
903
1078
  throw bridgeError("IDEMPOTENCY_COLLISION", "This local operation request identifier is already bound to different metadata.", false);
904
1079
  }
905
1080
  async #requireMatchingCubeRequest(clientRequestId, requestHash, persisted) {
906
- if (persisted.version === 3 || persisted.version === 4) {
1081
+ if (persisted.version === 3 || persisted.version === 4 || persisted.version === 5) {
907
1082
  const expected = await this.#hmacExisting(REQUEST_IDENTITY_DOMAIN, requestHash);
908
1083
  if (!hmacEqual(persisted.requestIdentityHmac, expected)) {
909
1084
  throw bridgeError("IDEMPOTENCY_COLLISION", "This local operation request identifier is already bound to different metadata.", false);
@@ -39,7 +39,7 @@ export interface OperationManagerDriver {
39
39
  result?(record: JournalRecord, signal: AbortSignal): Promise<ParseResult | void>;
40
40
  }
41
41
  export interface OperationManagerOptions {
42
- readonly journal: Pick<OperationJournal, "beginIntent" | "migrateLegacyRecord" | "requestIdentityHmac" | "sourceLocatorHmac" | "transition" | "loadByRequestId" | "loadByOperationId" | "loadLatestByRequestIdentityHmac" | "loadLatestBySourceLocatorHmac" | "listRecoverable" | "strengthenResultDelivery">;
42
+ readonly journal: Pick<OperationJournal, "beginIntent" | "bindSettlementFacts" | "migrateLegacyRecord" | "requestIdentityHmac" | "sourceLocatorHmac" | "transition" | "loadByRequestId" | "loadByOperationId" | "loadLatestByRequestIdentityHmac" | "loadLatestBySourceLocatorHmac" | "listRecoverable" | "strengthenResultDelivery">;
43
43
  readonly driver: OperationManagerDriver;
44
44
  readonly presentResult?: (record: JournalRecord, canonicalResult: ParseResult) => Promise<ParseResult>;
45
45
  readonly now?: () => number;