conversationalist 0.0.9 → 0.0.11

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.
Files changed (71) hide show
  1. package/README.md +148 -30
  2. package/dist/adapters/anthropic/index.d.ts.map +1 -1
  3. package/dist/adapters/anthropic/index.js +255 -2
  4. package/dist/adapters/anthropic/index.js.map +8 -4
  5. package/dist/adapters/gemini/index.d.ts.map +1 -1
  6. package/dist/adapters/gemini/index.js +255 -3
  7. package/dist/adapters/gemini/index.js.map +8 -4
  8. package/dist/adapters/openai/index.d.ts.map +1 -1
  9. package/dist/adapters/openai/index.js +247 -3
  10. package/dist/adapters/openai/index.js.map +8 -4
  11. package/dist/context.d.ts +6 -0
  12. package/dist/context.d.ts.map +1 -1
  13. package/dist/conversation/append.d.ts +5 -0
  14. package/dist/conversation/append.d.ts.map +1 -1
  15. package/dist/conversation/create.d.ts +9 -0
  16. package/dist/conversation/create.d.ts.map +1 -1
  17. package/dist/conversation/index.d.ts +8 -3
  18. package/dist/conversation/index.d.ts.map +1 -1
  19. package/dist/conversation/integrity.d.ts +16 -0
  20. package/dist/conversation/integrity.d.ts.map +1 -0
  21. package/dist/conversation/modify.d.ts +8 -2
  22. package/dist/conversation/modify.d.ts.map +1 -1
  23. package/dist/conversation/serialization.d.ts +0 -17
  24. package/dist/conversation/serialization.d.ts.map +1 -1
  25. package/dist/conversation/system-messages.d.ts.map +1 -1
  26. package/dist/conversation/tool-interactions.d.ts +45 -0
  27. package/dist/conversation/tool-interactions.d.ts.map +1 -0
  28. package/dist/conversation/transform.d.ts.map +1 -1
  29. package/dist/conversation/validation.d.ts +8 -0
  30. package/dist/conversation/validation.d.ts.map +1 -0
  31. package/dist/errors.d.ts +6 -1
  32. package/dist/errors.d.ts.map +1 -1
  33. package/dist/export/index.js +249 -12
  34. package/dist/export/index.js.map +10 -6
  35. package/dist/guards.d.ts +13 -0
  36. package/dist/guards.d.ts.map +1 -0
  37. package/dist/history.d.ts +21 -8
  38. package/dist/history.d.ts.map +1 -1
  39. package/dist/index.d.ts +4 -3
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +2212 -259
  42. package/dist/index.js.map +26 -13
  43. package/dist/markdown/index.js +2169 -253
  44. package/dist/markdown/index.js.map +23 -12
  45. package/dist/schemas/index.d.ts +1 -1
  46. package/dist/schemas/index.d.ts.map +1 -1
  47. package/dist/schemas/index.js +38 -22
  48. package/dist/schemas/index.js.map +3 -3
  49. package/dist/schemas.d.ts +17 -37
  50. package/dist/schemas.d.ts.map +1 -1
  51. package/dist/streaming.d.ts.map +1 -1
  52. package/dist/types.d.ts +0 -4
  53. package/dist/types.d.ts.map +1 -1
  54. package/dist/utilities/index.d.ts +0 -1
  55. package/dist/utilities/index.d.ts.map +1 -1
  56. package/dist/utilities/markdown.d.ts.map +1 -1
  57. package/dist/utilities/tool-calls.d.ts +2 -6
  58. package/dist/utilities/tool-calls.d.ts.map +1 -1
  59. package/dist/utilities/tool-results.d.ts.map +1 -1
  60. package/dist/utilities/transient.d.ts.map +1 -1
  61. package/dist/utilities.d.ts +0 -1
  62. package/dist/utilities.d.ts.map +1 -1
  63. package/dist/versioning/index.d.ts +0 -1
  64. package/dist/versioning/index.d.ts.map +1 -1
  65. package/dist/versioning/index.js +1 -52
  66. package/dist/versioning/index.js.map +4 -5
  67. package/dist/with-conversation.d.ts +4 -1
  68. package/dist/with-conversation.d.ts.map +1 -1
  69. package/package.json +7 -4
  70. package/dist/conversation.d.ts +0 -109
  71. package/dist/conversation.d.ts.map +0 -1
@@ -2630,16 +2630,16 @@ var require_dumper = __commonJS((exports, module) => {
2630
2630
  this.usedDuplicates = null;
2631
2631
  }
2632
2632
  function indentString(string, spaces) {
2633
- var ind = common.repeat(" ", spaces), position = 0, next = -1, result = "", line, length = string.length;
2633
+ var ind = common.repeat(" ", spaces), position = 0, next2 = -1, result = "", line, length = string.length;
2634
2634
  while (position < length) {
2635
- next = string.indexOf(`
2635
+ next2 = string.indexOf(`
2636
2636
  `, position);
2637
- if (next === -1) {
2637
+ if (next2 === -1) {
2638
2638
  line = string.slice(position);
2639
2639
  position = length;
2640
2640
  } else {
2641
- line = string.slice(position, next + 1);
2642
- position = next + 1;
2641
+ line = string.slice(position, next2 + 1);
2642
+ position = next2 + 1;
2643
2643
  }
2644
2644
  if (line.length && line !== `
2645
2645
  `)
@@ -2800,17 +2800,17 @@ var require_dumper = __commonJS((exports, module) => {
2800
2800
  return line;
2801
2801
  var breakRe = / [^ ]/g;
2802
2802
  var match;
2803
- var start = 0, end, curr = 0, next = 0;
2803
+ var start = 0, end, curr = 0, next2 = 0;
2804
2804
  var result = "";
2805
2805
  while (match = breakRe.exec(line)) {
2806
- next = match.index;
2807
- if (next - start > width) {
2808
- end = curr > start ? curr : next;
2806
+ next2 = match.index;
2807
+ if (next2 - start > width) {
2808
+ end = curr > start ? curr : next2;
2809
2809
  result += `
2810
2810
  ` + line.slice(start, end);
2811
2811
  start = end + 1;
2812
2812
  }
2813
- curr = next;
2813
+ curr = next2;
2814
2814
  }
2815
2815
  result += `
2816
2816
  `;
@@ -3491,6 +3491,1773 @@ var require_gray_matter = __commonJS((exports, module) => {
3491
3491
  module.exports = matter;
3492
3492
  });
3493
3493
 
3494
+ // node_modules/event-emission/dist/index.js
3495
+ var SymbolObservable = typeof Symbol === "function" && Symbol.observable || Symbol.for("@@observable");
3496
+ if (typeof Symbol === "function") {
3497
+ Symbol.observable = SymbolObservable;
3498
+ }
3499
+ function getMethod(obj, key) {
3500
+ if (obj === null || obj === undefined)
3501
+ return;
3502
+ const value = obj[key];
3503
+ if (value == null)
3504
+ return;
3505
+ if (typeof value !== "function") {
3506
+ throw new TypeError(value + " is not a function");
3507
+ }
3508
+ return value;
3509
+ }
3510
+ function hostReportError(e) {
3511
+ if (typeof queueMicrotask === "function") {
3512
+ queueMicrotask(() => {
3513
+ throw e;
3514
+ });
3515
+ } else {
3516
+ setTimeout(() => {
3517
+ throw e;
3518
+ });
3519
+ }
3520
+ }
3521
+ function SubscriptionObserverImpl(subscription) {
3522
+ this._subscription = subscription;
3523
+ }
3524
+ SubscriptionObserverImpl.prototype = Object.create(Object.prototype);
3525
+ Object.defineProperties(SubscriptionObserverImpl.prototype, {
3526
+ constructor: { value: Object, configurable: true, writable: true },
3527
+ closed: {
3528
+ get() {
3529
+ return this._subscription._closed;
3530
+ },
3531
+ configurable: true
3532
+ },
3533
+ next: {
3534
+ value: function next(value) {
3535
+ const subscription = this._subscription;
3536
+ if (subscription._closed)
3537
+ return;
3538
+ const observer = subscription._observer;
3539
+ try {
3540
+ const m = getMethod(observer, "next");
3541
+ if (!m)
3542
+ return;
3543
+ return m.call(observer, value);
3544
+ } catch (e) {
3545
+ try {
3546
+ this.error(e);
3547
+ } catch (err) {
3548
+ hostReportError(err);
3549
+ }
3550
+ }
3551
+ },
3552
+ configurable: true,
3553
+ writable: true
3554
+ },
3555
+ error: {
3556
+ value: function error(errorValue) {
3557
+ const subscription = this._subscription;
3558
+ if (subscription._closed)
3559
+ throw errorValue;
3560
+ subscription._closed = true;
3561
+ const observer = subscription._observer;
3562
+ try {
3563
+ const m = getMethod(observer, "error");
3564
+ if (m) {
3565
+ return m.call(observer, errorValue);
3566
+ }
3567
+ throw errorValue;
3568
+ } finally {
3569
+ subscription._cleanup();
3570
+ }
3571
+ },
3572
+ configurable: true,
3573
+ writable: true
3574
+ },
3575
+ complete: {
3576
+ value: function complete(value) {
3577
+ const subscription = this._subscription;
3578
+ if (subscription._closed)
3579
+ return;
3580
+ subscription._closed = true;
3581
+ const observer = subscription._observer;
3582
+ try {
3583
+ const m = getMethod(observer, "complete");
3584
+ if (m) {
3585
+ return m.call(observer, value);
3586
+ }
3587
+ return;
3588
+ } finally {
3589
+ subscription._cleanup();
3590
+ }
3591
+ },
3592
+ configurable: true,
3593
+ writable: true
3594
+ }
3595
+ });
3596
+ Object.defineProperty(SubscriptionObserverImpl.prototype.next, "length", { value: 1 });
3597
+ Object.defineProperty(SubscriptionObserverImpl.prototype.error, "length", { value: 1 });
3598
+ Object.defineProperty(SubscriptionObserverImpl.prototype.complete, "length", {
3599
+ value: 1
3600
+ });
3601
+ function Subscription(observer, subscriber) {
3602
+ this._observer = observer;
3603
+ this._cleanupFn = undefined;
3604
+ this._closed = false;
3605
+ const subscriptionObserver = new SubscriptionObserverImpl(this);
3606
+ try {
3607
+ const start = getMethod(observer, "start");
3608
+ if (start) {
3609
+ start.call(observer, this);
3610
+ }
3611
+ } catch (e) {
3612
+ hostReportError(e);
3613
+ }
3614
+ if (this._closed)
3615
+ return;
3616
+ try {
3617
+ const cleanup = subscriber(subscriptionObserver);
3618
+ if (cleanup != null) {
3619
+ if (typeof cleanup !== "function" && typeof cleanup.unsubscribe !== "function") {
3620
+ throw new TypeError(cleanup + " is not a function or a subscription");
3621
+ }
3622
+ this._cleanupFn = cleanup;
3623
+ if (this._closed) {
3624
+ this._cleanup();
3625
+ }
3626
+ }
3627
+ } catch (e) {
3628
+ subscriptionObserver.error(e);
3629
+ }
3630
+ }
3631
+ Subscription.prototype = Object.create(Object.prototype);
3632
+ Object.defineProperties(Subscription.prototype, {
3633
+ constructor: { value: Object, configurable: true, writable: true },
3634
+ closed: {
3635
+ get() {
3636
+ return this._closed;
3637
+ },
3638
+ configurable: true
3639
+ },
3640
+ unsubscribe: {
3641
+ value: function unsubscribe() {
3642
+ if (this._closed)
3643
+ return;
3644
+ this._closed = true;
3645
+ this._cleanup();
3646
+ },
3647
+ configurable: true,
3648
+ writable: true
3649
+ },
3650
+ _cleanup: {
3651
+ value: function _cleanup() {
3652
+ const cleanup = this._cleanupFn;
3653
+ if (!cleanup)
3654
+ return;
3655
+ this._cleanupFn = undefined;
3656
+ try {
3657
+ if (typeof cleanup === "function") {
3658
+ cleanup();
3659
+ } else if (cleanup && typeof cleanup.unsubscribe === "function") {
3660
+ cleanup.unsubscribe();
3661
+ }
3662
+ } catch (e) {
3663
+ hostReportError(e);
3664
+ }
3665
+ },
3666
+ configurable: true,
3667
+ writable: true
3668
+ }
3669
+ });
3670
+
3671
+ class Observable {
3672
+ _subscriber;
3673
+ constructor(subscriber) {
3674
+ if (typeof subscriber !== "function") {
3675
+ throw new TypeError("Observable initializer must be a function");
3676
+ }
3677
+ this._subscriber = subscriber;
3678
+ }
3679
+ subscribe(observerOrNext, error2, complete2) {
3680
+ let observer;
3681
+ if (typeof observerOrNext === "function") {
3682
+ observer = {
3683
+ next: observerOrNext,
3684
+ error: error2,
3685
+ complete: complete2
3686
+ };
3687
+ } else if (typeof observerOrNext !== "object" || observerOrNext === null) {
3688
+ throw new TypeError(observerOrNext + " is not an object");
3689
+ } else {
3690
+ observer = observerOrNext;
3691
+ }
3692
+ return new Subscription(observer, this._subscriber);
3693
+ }
3694
+ [SymbolObservable]() {
3695
+ return this;
3696
+ }
3697
+ static of(...items) {
3698
+ const C = typeof this === "function" ? this : Observable;
3699
+ return new C((observer) => {
3700
+ for (let i = 0;i < items.length; ++i) {
3701
+ observer.next(items[i]);
3702
+ if (observer.closed)
3703
+ return;
3704
+ }
3705
+ observer.complete();
3706
+ });
3707
+ }
3708
+ static from(x) {
3709
+ const C = typeof this === "function" ? this : Observable;
3710
+ if (x == null)
3711
+ throw new TypeError(x + " is not an object");
3712
+ const method = x[SymbolObservable];
3713
+ if (method != null) {
3714
+ if (typeof method !== "function") {
3715
+ throw new TypeError(method + " is not a function");
3716
+ }
3717
+ const observable = method.call(x);
3718
+ if (Object(observable) !== observable) {
3719
+ throw new TypeError(observable + " is not an object");
3720
+ }
3721
+ if (observable.constructor === C) {
3722
+ return observable;
3723
+ }
3724
+ return new C((observer) => observable.subscribe(observer));
3725
+ }
3726
+ if (Symbol.iterator in x) {
3727
+ return new C((observer) => {
3728
+ for (const item of x) {
3729
+ observer.next(item);
3730
+ if (observer.closed)
3731
+ return;
3732
+ }
3733
+ observer.complete();
3734
+ });
3735
+ }
3736
+ throw new TypeError(x + " is not observable");
3737
+ }
3738
+ }
3739
+ var PROXY_MARKER = Symbol.for("@lasercat/event-emission/proxy");
3740
+ var ORIGINAL_TARGET = Symbol.for("@lasercat/event-emission/original");
3741
+ var ARRAY_MUTATORS = new Set([
3742
+ "push",
3743
+ "pop",
3744
+ "shift",
3745
+ "unshift",
3746
+ "splice",
3747
+ "sort",
3748
+ "reverse",
3749
+ "fill",
3750
+ "copyWithin"
3751
+ ]);
3752
+ function isProxyable(value) {
3753
+ return value !== null && typeof value === "object" && !isProxied(value) && !(value instanceof Date) && !(value instanceof RegExp) && !(value instanceof Map) && !(value instanceof Set) && !(value instanceof WeakMap) && !(value instanceof WeakSet) && !(value instanceof Promise) && !(value instanceof Error) && !(value instanceof ArrayBuffer) && !ArrayBuffer.isView(value);
3754
+ }
3755
+ function isProxied(value) {
3756
+ return typeof value === "object" && value !== null && value[PROXY_MARKER] === true;
3757
+ }
3758
+ function isArrayMutator(prop) {
3759
+ return typeof prop === "string" && ARRAY_MUTATORS.has(prop);
3760
+ }
3761
+ function cloneAlongPath(obj, path) {
3762
+ const isArray = Array.isArray(obj);
3763
+ const rootClone = isArray ? [...obj] : { ...obj };
3764
+ if (!path || isArray) {
3765
+ return rootClone;
3766
+ }
3767
+ const parts = path.split(".");
3768
+ const result = rootClone;
3769
+ let current = result;
3770
+ for (let i = 0;i < parts.length; i++) {
3771
+ const key = parts[i];
3772
+ const value = current[key];
3773
+ if (value !== null && typeof value === "object") {
3774
+ current[key] = Array.isArray(value) ? [...value] : { ...value };
3775
+ if (i < parts.length - 1) {
3776
+ current = current[key];
3777
+ }
3778
+ } else {
3779
+ break;
3780
+ }
3781
+ }
3782
+ return result;
3783
+ }
3784
+ function cloneForComparison(obj, strategy, changedPath, deepClone) {
3785
+ if (obj === null || typeof obj !== "object")
3786
+ return obj;
3787
+ switch (strategy) {
3788
+ case "shallow":
3789
+ return Array.isArray(obj) ? [...obj] : { ...obj };
3790
+ case "deep":
3791
+ if (deepClone) {
3792
+ return deepClone(obj);
3793
+ }
3794
+ if (typeof structuredClone !== "function") {
3795
+ throw new Error("structuredClone is not available in this runtime; provide observe.deepClone, or use cloneStrategy 'path' or 'shallow'.");
3796
+ }
3797
+ return structuredClone(obj);
3798
+ case "path":
3799
+ return cloneAlongPath(obj, changedPath);
3800
+ default:
3801
+ return obj;
3802
+ }
3803
+ }
3804
+ function computeArrayDiff(method, before, _after, args) {
3805
+ switch (method) {
3806
+ case "push":
3807
+ return { added: args };
3808
+ case "pop":
3809
+ return { removed: before.length > 0 ? [before[before.length - 1]] : [] };
3810
+ case "shift":
3811
+ return { removed: before.length > 0 ? [before[0]] : [] };
3812
+ case "unshift":
3813
+ return { added: args };
3814
+ case "splice": {
3815
+ const [start, deleteCount, ...items] = args;
3816
+ const actualStart = start < 0 ? Math.max(before.length + start, 0) : Math.min(start, before.length);
3817
+ const actualDeleteCount = Math.min(deleteCount ?? before.length - actualStart, before.length - actualStart);
3818
+ return {
3819
+ removed: before.slice(actualStart, actualStart + actualDeleteCount),
3820
+ added: items
3821
+ };
3822
+ }
3823
+ case "sort":
3824
+ case "reverse":
3825
+ case "fill":
3826
+ case "copyWithin":
3827
+ return {};
3828
+ default:
3829
+ return {};
3830
+ }
3831
+ }
3832
+ var proxyRegistry = new WeakMap;
3833
+ function getContextRegistry(target) {
3834
+ let contextMap = proxyRegistry.get(target);
3835
+ if (!contextMap) {
3836
+ contextMap = new WeakMap;
3837
+ proxyRegistry.set(target, contextMap);
3838
+ }
3839
+ return contextMap;
3840
+ }
3841
+ function createArrayMethodInterceptor(array, method, path, context) {
3842
+ const original = array[method];
3843
+ return function(...args) {
3844
+ const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, path, context.options.deepClone);
3845
+ const previousItems = [...array];
3846
+ const result = original.apply(this, args);
3847
+ const { added, removed } = computeArrayDiff(method, previousItems, array, args);
3848
+ const methodEventPath = path ? `update:${path}.${method}` : `update:${method}`;
3849
+ const arrayEventPath = path ? `update:${path}` : "update:";
3850
+ context.eventTarget.dispatchEvent({
3851
+ type: methodEventPath,
3852
+ detail: {
3853
+ method,
3854
+ args,
3855
+ result,
3856
+ added,
3857
+ removed,
3858
+ current: context.originalRoot,
3859
+ previous: previousState
3860
+ }
3861
+ });
3862
+ if (path) {
3863
+ context.eventTarget.dispatchEvent({
3864
+ type: arrayEventPath,
3865
+ detail: {
3866
+ value: array,
3867
+ current: context.originalRoot,
3868
+ previous: previousState
3869
+ }
3870
+ });
3871
+ }
3872
+ context.eventTarget.dispatchEvent({
3873
+ type: "update",
3874
+ detail: {
3875
+ current: context.originalRoot,
3876
+ previous: previousState
3877
+ }
3878
+ });
3879
+ return result;
3880
+ };
3881
+ }
3882
+ function createObservableProxyInternal(target, path, context) {
3883
+ const contextRegistry = getContextRegistry(target);
3884
+ const existing = contextRegistry.get(context);
3885
+ if (existing) {
3886
+ return existing.proxy;
3887
+ }
3888
+ const proxy = new Proxy(target, {
3889
+ get(obj, prop, receiver) {
3890
+ if (prop === PROXY_MARKER)
3891
+ return true;
3892
+ if (prop === ORIGINAL_TARGET)
3893
+ return obj;
3894
+ if (typeof prop === "symbol") {
3895
+ return Reflect.get(obj, prop, receiver);
3896
+ }
3897
+ const value = Reflect.get(obj, prop, receiver);
3898
+ if (Array.isArray(obj) && isArrayMutator(prop)) {
3899
+ return createArrayMethodInterceptor(obj, prop, path, context);
3900
+ }
3901
+ if (context.options.deep && isProxyable(value)) {
3902
+ const nestedPath = path ? `${path}.${prop}` : prop;
3903
+ return createObservableProxyInternal(value, nestedPath, context);
3904
+ }
3905
+ return value;
3906
+ },
3907
+ set(obj, prop, value, receiver) {
3908
+ if (typeof prop === "symbol") {
3909
+ return Reflect.set(obj, prop, value, receiver);
3910
+ }
3911
+ const oldValue = Reflect.get(obj, prop, receiver);
3912
+ if (Object.is(oldValue, value)) {
3913
+ return true;
3914
+ }
3915
+ const propPath = path ? `${path}.${prop}` : prop;
3916
+ const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath, context.options.deepClone);
3917
+ const success = Reflect.set(obj, prop, value, receiver);
3918
+ if (success) {
3919
+ context.eventTarget.dispatchEvent({
3920
+ type: `update:${propPath}`,
3921
+ detail: {
3922
+ value,
3923
+ current: context.originalRoot,
3924
+ previous: previousState
3925
+ }
3926
+ });
3927
+ context.eventTarget.dispatchEvent({
3928
+ type: "update",
3929
+ detail: {
3930
+ current: context.originalRoot,
3931
+ previous: previousState
3932
+ }
3933
+ });
3934
+ }
3935
+ return success;
3936
+ },
3937
+ deleteProperty(obj, prop) {
3938
+ if (typeof prop === "symbol") {
3939
+ return Reflect.deleteProperty(obj, prop);
3940
+ }
3941
+ const propPath = path ? `${path}.${String(prop)}` : String(prop);
3942
+ const previousState = cloneForComparison(context.originalRoot, context.options.cloneStrategy, propPath, context.options.deepClone);
3943
+ const success = Reflect.deleteProperty(obj, prop);
3944
+ if (success) {
3945
+ context.eventTarget.dispatchEvent({
3946
+ type: `update:${propPath}`,
3947
+ detail: {
3948
+ value: undefined,
3949
+ current: context.originalRoot,
3950
+ previous: previousState
3951
+ }
3952
+ });
3953
+ context.eventTarget.dispatchEvent({
3954
+ type: "update",
3955
+ detail: {
3956
+ current: context.originalRoot,
3957
+ previous: previousState
3958
+ }
3959
+ });
3960
+ }
3961
+ return success;
3962
+ }
3963
+ });
3964
+ contextRegistry.set(context, {
3965
+ proxy,
3966
+ path
3967
+ });
3968
+ return proxy;
3969
+ }
3970
+ function isEventTarget(obj) {
3971
+ return typeof obj === "object" && obj !== null && typeof obj.addEventListener === "function" && typeof obj.removeEventListener === "function" && typeof obj.dispatchEvent === "function";
3972
+ }
3973
+ function setupEventForwarding(source, target) {
3974
+ const handlers = new Map;
3975
+ const sourceAddEventListener = source.addEventListener.bind(source);
3976
+ const sourceRemoveEventListener = source.removeEventListener.bind(source);
3977
+ const forwardHandler = (type) => (event) => {
3978
+ const detail = event.detail ?? event;
3979
+ target.dispatchEvent({
3980
+ type,
3981
+ detail
3982
+ });
3983
+ };
3984
+ const originalAddEventListener = target.addEventListener.bind(target);
3985
+ const wrappedAddEventListener = (type, listener, options2) => {
3986
+ if (!handlers.has(type) && type !== "update" && !type.startsWith("update:")) {
3987
+ const handler = forwardHandler(type);
3988
+ handlers.set(type, handler);
3989
+ sourceAddEventListener(type, handler);
3990
+ }
3991
+ return originalAddEventListener(type, listener, options2);
3992
+ };
3993
+ target.addEventListener = wrappedAddEventListener;
3994
+ return () => {
3995
+ target.addEventListener = originalAddEventListener;
3996
+ for (const [type, handler] of handlers) {
3997
+ sourceRemoveEventListener(type, handler);
3998
+ }
3999
+ handlers.clear();
4000
+ };
4001
+ }
4002
+ function createObservableProxy(target, eventTarget, options2) {
4003
+ const resolvedOptions = {
4004
+ deep: options2?.deep ?? true,
4005
+ cloneStrategy: options2?.cloneStrategy ?? "path",
4006
+ deepClone: options2?.deepClone
4007
+ };
4008
+ const context = {
4009
+ eventTarget,
4010
+ originalRoot: target,
4011
+ options: resolvedOptions
4012
+ };
4013
+ const proxy = createObservableProxyInternal(target, "", context);
4014
+ if (isEventTarget(target)) {
4015
+ const cleanupForwarding = setupEventForwarding(target, eventTarget);
4016
+ const maybeComplete = eventTarget.complete;
4017
+ if (typeof maybeComplete === "function") {
4018
+ const originalComplete = maybeComplete.bind(eventTarget);
4019
+ let cleaned = false;
4020
+ eventTarget.complete = () => {
4021
+ if (!cleaned) {
4022
+ cleaned = true;
4023
+ cleanupForwarding();
4024
+ }
4025
+ return originalComplete();
4026
+ };
4027
+ }
4028
+ }
4029
+ return proxy;
4030
+ }
4031
+
4032
+ class BufferOverflowError extends Error {
4033
+ constructor(eventType, bufferSize) {
4034
+ super(`Buffer overflow for event type "${eventType}" (max: ${bufferSize})`);
4035
+ this.name = "BufferOverflowError";
4036
+ }
4037
+ }
4038
+ function matchesWildcard(eventType, pattern) {
4039
+ if (pattern === "*")
4040
+ return true;
4041
+ return pattern.endsWith(":*") && eventType.startsWith(pattern.slice(0, -2) + ":");
4042
+ }
4043
+ var EVENT_STATE = Symbol("event-emission:event-state");
4044
+ function createEventTarget(targetOrOpts, opts) {
4045
+ if (opts?.observe === true && targetOrOpts && typeof targetOrOpts === "object") {
4046
+ const target = targetOrOpts;
4047
+ const eventTarget = createEventTargetInternal({
4048
+ onListenerError: opts.onListenerError
4049
+ });
4050
+ const proxy = createObservableProxy(target, eventTarget, {
4051
+ deep: opts.deep,
4052
+ cloneStrategy: opts.cloneStrategy,
4053
+ deepClone: opts.deepClone
4054
+ });
4055
+ const methodNames = [
4056
+ "addEventListener",
4057
+ "removeEventListener",
4058
+ "dispatchEvent",
4059
+ "clear",
4060
+ "on",
4061
+ "once",
4062
+ "removeAllListeners",
4063
+ "pipe",
4064
+ "addWildcardListener",
4065
+ "removeWildcardListener",
4066
+ "complete",
4067
+ "subscribe",
4068
+ "toObservable",
4069
+ "events"
4070
+ ];
4071
+ for (const name of methodNames) {
4072
+ Object.defineProperty(proxy, name, {
4073
+ value: eventTarget[name],
4074
+ writable: false,
4075
+ enumerable: false,
4076
+ configurable: true
4077
+ });
4078
+ }
4079
+ Object.defineProperty(proxy, "completed", {
4080
+ get: () => eventTarget.completed,
4081
+ enumerable: false,
4082
+ configurable: true
4083
+ });
4084
+ return proxy;
4085
+ }
4086
+ return createEventTargetInternal(targetOrOpts);
4087
+ }
4088
+ function createEventTargetInternal(opts) {
4089
+ const listeners = new Map;
4090
+ const wildcardListeners = new Set;
4091
+ let isCompleted = false;
4092
+ const completionCallbacks = new Set;
4093
+ const now = () => typeof globalThis.performance?.now === "function" ? globalThis.performance.now() : Date.now();
4094
+ const initializeEventState = (state, type, bubbles, cancelable) => {
4095
+ state.initializedFlag = true;
4096
+ state.stopPropagationFlag = false;
4097
+ state.stopImmediatePropagationFlag = false;
4098
+ state.canceledFlag = false;
4099
+ state.isTrusted = false;
4100
+ state.target = null;
4101
+ state.currentTarget = null;
4102
+ state.eventPhase = 0;
4103
+ state.type = type;
4104
+ state.bubbles = bubbles;
4105
+ state.cancelable = cancelable;
4106
+ };
4107
+ const setCanceledFlag = (state) => {
4108
+ if (state.cancelable && !state.inPassiveListenerFlag) {
4109
+ state.canceledFlag = true;
4110
+ }
4111
+ };
4112
+ const createEvent = (type, detail, init) => {
4113
+ const state = {
4114
+ dispatchFlag: false,
4115
+ initializedFlag: true,
4116
+ stopPropagationFlag: false,
4117
+ stopImmediatePropagationFlag: false,
4118
+ canceledFlag: false,
4119
+ inPassiveListenerFlag: false,
4120
+ composedFlag: Boolean(init?.composed),
4121
+ eventPhase: init?.eventPhase ?? 0,
4122
+ currentTarget: init?.currentTarget ?? init?.target ?? null,
4123
+ target: init?.target ?? null,
4124
+ timeStamp: init?.timeStamp ?? now(),
4125
+ path: [],
4126
+ type,
4127
+ bubbles: Boolean(init?.bubbles),
4128
+ cancelable: Boolean(init?.cancelable),
4129
+ isTrusted: false
4130
+ };
4131
+ const event = { detail };
4132
+ Object.defineProperties(event, {
4133
+ type: {
4134
+ get: () => state.type,
4135
+ enumerable: true,
4136
+ configurable: true
4137
+ },
4138
+ bubbles: {
4139
+ get: () => state.bubbles,
4140
+ enumerable: true,
4141
+ configurable: true
4142
+ },
4143
+ cancelable: {
4144
+ get: () => state.cancelable,
4145
+ enumerable: true,
4146
+ configurable: true
4147
+ },
4148
+ cancelBubble: {
4149
+ get: () => state.stopPropagationFlag,
4150
+ set: (value) => {
4151
+ if (value)
4152
+ state.stopPropagationFlag = true;
4153
+ },
4154
+ enumerable: true,
4155
+ configurable: true
4156
+ },
4157
+ composed: {
4158
+ get: () => state.composedFlag,
4159
+ enumerable: true,
4160
+ configurable: true
4161
+ },
4162
+ currentTarget: {
4163
+ get: () => state.currentTarget,
4164
+ enumerable: true,
4165
+ configurable: true
4166
+ },
4167
+ defaultPrevented: {
4168
+ get: () => state.canceledFlag,
4169
+ enumerable: true,
4170
+ configurable: true
4171
+ },
4172
+ eventPhase: {
4173
+ get: () => state.eventPhase,
4174
+ enumerable: true,
4175
+ configurable: true
4176
+ },
4177
+ isTrusted: {
4178
+ get: () => state.isTrusted,
4179
+ enumerable: true,
4180
+ configurable: true
4181
+ },
4182
+ returnValue: {
4183
+ get: () => !state.canceledFlag,
4184
+ set: (value) => {
4185
+ if (value === false)
4186
+ setCanceledFlag(state);
4187
+ },
4188
+ enumerable: true,
4189
+ configurable: true
4190
+ },
4191
+ srcElement: {
4192
+ get: () => state.target,
4193
+ enumerable: true,
4194
+ configurable: true
4195
+ },
4196
+ target: {
4197
+ get: () => state.target,
4198
+ enumerable: true,
4199
+ configurable: true
4200
+ },
4201
+ timeStamp: {
4202
+ get: () => state.timeStamp,
4203
+ enumerable: true,
4204
+ configurable: true
4205
+ },
4206
+ composedPath: {
4207
+ value: () => state.path.map((entry) => entry.invocationTarget),
4208
+ enumerable: true,
4209
+ configurable: true
4210
+ },
4211
+ initEvent: {
4212
+ value: (newType, bubbles = false, cancelable = false) => {
4213
+ if (state.dispatchFlag)
4214
+ return;
4215
+ initializeEventState(state, newType, Boolean(bubbles), Boolean(cancelable));
4216
+ },
4217
+ enumerable: true,
4218
+ configurable: true
4219
+ },
4220
+ preventDefault: {
4221
+ value: () => setCanceledFlag(state),
4222
+ enumerable: true,
4223
+ configurable: true
4224
+ },
4225
+ stopImmediatePropagation: {
4226
+ value: () => {
4227
+ state.stopPropagationFlag = true;
4228
+ state.stopImmediatePropagationFlag = true;
4229
+ },
4230
+ enumerable: true,
4231
+ configurable: true
4232
+ },
4233
+ stopPropagation: {
4234
+ value: () => {
4235
+ state.stopPropagationFlag = true;
4236
+ },
4237
+ enumerable: true,
4238
+ configurable: true
4239
+ },
4240
+ NONE: { value: 0, enumerable: true, configurable: true },
4241
+ CAPTURING_PHASE: { value: 1, enumerable: true, configurable: true },
4242
+ AT_TARGET: { value: 2, enumerable: true, configurable: true },
4243
+ BUBBLING_PHASE: { value: 3, enumerable: true, configurable: true },
4244
+ [EVENT_STATE]: {
4245
+ value: state,
4246
+ enumerable: false,
4247
+ configurable: false
4248
+ }
4249
+ });
4250
+ return event;
4251
+ };
4252
+ const getEventState = (event) => event[EVENT_STATE];
4253
+ const normalizeAddListenerOptions = (options2) => {
4254
+ if (typeof options2 === "boolean") {
4255
+ return {
4256
+ capture: options2,
4257
+ passive: false,
4258
+ once: false,
4259
+ signal: null
4260
+ };
4261
+ }
4262
+ return {
4263
+ capture: Boolean(options2?.capture),
4264
+ passive: Boolean(options2?.passive),
4265
+ once: Boolean(options2?.once),
4266
+ signal: options2?.signal ?? null
4267
+ };
4268
+ };
4269
+ const normalizeCaptureOption = (options2) => {
4270
+ if (typeof options2 === "boolean")
4271
+ return options2;
4272
+ return Boolean(options2?.capture);
4273
+ };
4274
+ const removeListenerRecord = (type, record) => {
4275
+ if (record.removed)
4276
+ return;
4277
+ record.removed = true;
4278
+ const list = listeners.get(type);
4279
+ if (list) {
4280
+ const idx = list.indexOf(record);
4281
+ if (idx >= 0)
4282
+ list.splice(idx, 1);
4283
+ if (list.length === 0)
4284
+ listeners.delete(type);
4285
+ }
4286
+ if (record.signal && record.abortHandler) {
4287
+ record.signal.removeEventListener("abort", record.abortHandler);
4288
+ }
4289
+ };
4290
+ const handleListenerError = (eventType, error2) => {
4291
+ if (eventType === "error")
4292
+ return;
4293
+ if (opts?.onListenerError) {
4294
+ opts.onListenerError(eventType, error2);
4295
+ return;
4296
+ }
4297
+ const errorListeners = listeners.get("error");
4298
+ if (errorListeners && errorListeners.length > 0) {
4299
+ dispatchEvent({ type: "error", detail: error2 });
4300
+ } else {
4301
+ throw error2;
4302
+ }
4303
+ };
4304
+ const notifyWildcardListeners = (eventType, event) => {
4305
+ if (wildcardListeners.size === 0)
4306
+ return;
4307
+ for (const rec of Array.from(wildcardListeners)) {
4308
+ if (!matchesWildcard(eventType, rec.pattern))
4309
+ continue;
4310
+ const baseEvent = createEvent(rec.pattern, event.detail, {
4311
+ target,
4312
+ currentTarget: target,
4313
+ eventPhase: 2,
4314
+ bubbles: event.bubbles,
4315
+ cancelable: event.cancelable,
4316
+ composed: event.composed
4317
+ });
4318
+ const wildcardEvent = Object.defineProperties(baseEvent, {
4319
+ originalType: { value: eventType, enumerable: true, configurable: true }
4320
+ });
4321
+ try {
4322
+ const fn = rec.fn;
4323
+ const res = fn(wildcardEvent);
4324
+ if (res && typeof res.then === "function") {
4325
+ res.catch((error2) => {
4326
+ try {
4327
+ handleListenerError(eventType, error2);
4328
+ } catch (rethrown) {
4329
+ queueMicrotask(() => {
4330
+ throw rethrown;
4331
+ });
4332
+ }
4333
+ });
4334
+ }
4335
+ } catch (error2) {
4336
+ handleListenerError(eventType, error2);
4337
+ } finally {
4338
+ if (rec.once)
4339
+ wildcardListeners.delete(rec);
4340
+ }
4341
+ const state = getEventState(wildcardEvent);
4342
+ if (state?.stopImmediatePropagationFlag || state?.stopPropagationFlag) {
4343
+ break;
4344
+ }
4345
+ }
4346
+ };
4347
+ const addEventListener = (type, listener, options2) => {
4348
+ if (isCompleted || !listener) {
4349
+ return () => {};
4350
+ }
4351
+ const { capture, passive, once, signal } = normalizeAddListenerOptions(options2);
4352
+ let list = listeners.get(type);
4353
+ if (!list) {
4354
+ list = [];
4355
+ listeners.set(type, list);
4356
+ }
4357
+ for (const existing of list) {
4358
+ if (existing.original === listener && existing.capture === capture) {
4359
+ return () => removeEventListener(type, listener, options2);
4360
+ }
4361
+ }
4362
+ const original = listener;
4363
+ const callback = typeof listener === "function" ? listener : (event) => listener.handleEvent(event);
4364
+ const record = {
4365
+ type,
4366
+ original,
4367
+ callback,
4368
+ capture,
4369
+ passive,
4370
+ once,
4371
+ signal,
4372
+ removed: false
4373
+ };
4374
+ list.push(record);
4375
+ const unsubscribe2 = () => removeListenerRecord(type, record);
4376
+ if (signal) {
4377
+ const onAbort = () => removeListenerRecord(type, record);
4378
+ record.abortHandler = onAbort;
4379
+ signal.addEventListener("abort", onAbort, { once: true });
4380
+ if (signal.aborted)
4381
+ onAbort();
4382
+ }
4383
+ return unsubscribe2;
4384
+ };
4385
+ const addWildcardListener = (pattern, listener, options2) => {
4386
+ if (isCompleted)
4387
+ return () => {};
4388
+ const opts2 = options2 ?? {};
4389
+ for (const existing of wildcardListeners) {
4390
+ if (existing.pattern === pattern && existing.fn === listener) {
4391
+ return () => removeWildcardListener(pattern, listener);
4392
+ }
4393
+ }
4394
+ const record = {
4395
+ fn: listener,
4396
+ pattern,
4397
+ once: opts2.once,
4398
+ signal: opts2.signal
4399
+ };
4400
+ wildcardListeners.add(record);
4401
+ const unsubscribe2 = () => {
4402
+ wildcardListeners.delete(record);
4403
+ if (record.signal && record.abortHandler) {
4404
+ record.signal.removeEventListener("abort", record.abortHandler);
4405
+ }
4406
+ };
4407
+ if (opts2.signal) {
4408
+ const onAbort = () => unsubscribe2();
4409
+ record.abortHandler = onAbort;
4410
+ opts2.signal.addEventListener("abort", onAbort, { once: true });
4411
+ if (opts2.signal.aborted)
4412
+ onAbort();
4413
+ }
4414
+ return unsubscribe2;
4415
+ };
4416
+ const removeWildcardListener = (pattern, listener) => {
4417
+ for (const record of Array.from(wildcardListeners)) {
4418
+ if (record.pattern === pattern && record.fn === listener) {
4419
+ wildcardListeners.delete(record);
4420
+ if (record.signal && record.abortHandler) {
4421
+ record.signal.removeEventListener("abort", record.abortHandler);
4422
+ }
4423
+ }
4424
+ }
4425
+ };
4426
+ const invokeListeners = (eventType, event, phase, listenersSnapshot) => {
4427
+ const state = getEventState(event);
4428
+ if (!state || state.stopPropagationFlag)
4429
+ return;
4430
+ state.currentTarget = target;
4431
+ state.target = target;
4432
+ state.eventPhase = event.AT_TARGET;
4433
+ for (const rec of listenersSnapshot) {
4434
+ if (rec.removed)
4435
+ continue;
4436
+ if (phase === "capturing" && !rec.capture)
4437
+ continue;
4438
+ if (phase === "bubbling" && rec.capture)
4439
+ continue;
4440
+ if (rec.once)
4441
+ removeListenerRecord(rec.type, rec);
4442
+ if (rec.passive)
4443
+ state.inPassiveListenerFlag = true;
4444
+ try {
4445
+ const res = rec.callback.call(state.currentTarget, event);
4446
+ if (res && typeof res.then === "function") {
4447
+ res.catch((error2) => {
4448
+ try {
4449
+ handleListenerError(eventType, error2);
4450
+ } catch (rethrown) {
4451
+ queueMicrotask(() => {
4452
+ throw rethrown;
4453
+ });
4454
+ }
4455
+ });
4456
+ }
4457
+ } catch (error2) {
4458
+ handleListenerError(eventType, error2);
4459
+ } finally {
4460
+ if (rec.passive)
4461
+ state.inPassiveListenerFlag = false;
4462
+ }
4463
+ if (state.stopImmediatePropagationFlag)
4464
+ break;
4465
+ }
4466
+ };
4467
+ const dispatchEvent = (eventInput) => {
4468
+ if (isCompleted)
4469
+ return false;
4470
+ let event;
4471
+ let state;
4472
+ if (eventInput && typeof eventInput === "object") {
4473
+ state = getEventState(eventInput);
4474
+ if (state) {
4475
+ event = eventInput;
4476
+ } else {
4477
+ const input = eventInput;
4478
+ if (typeof input.type !== "string") {
4479
+ throw new TypeError("Event type must be a string");
4480
+ }
4481
+ event = createEvent(input.type, input.detail, {
4482
+ bubbles: input.bubbles,
4483
+ cancelable: input.cancelable,
4484
+ composed: input.composed,
4485
+ timeStamp: input.timeStamp
4486
+ });
4487
+ state = getEventState(event);
4488
+ }
4489
+ } else {
4490
+ throw new TypeError("dispatchEvent expects an event object");
4491
+ }
4492
+ const dispatchState = state ?? getEventState(event);
4493
+ if (dispatchState.dispatchFlag || !dispatchState.initializedFlag) {
4494
+ const message = "Failed to execute dispatchEvent: event is already being dispatched";
4495
+ if (typeof globalThis.DOMException === "function") {
4496
+ throw new globalThis.DOMException(message, "InvalidStateError");
4497
+ }
4498
+ const err = new Error(message);
4499
+ err.name = "InvalidStateError";
4500
+ throw err;
4501
+ }
4502
+ dispatchState.isTrusted = false;
4503
+ dispatchState.dispatchFlag = true;
4504
+ dispatchState.path = [
4505
+ {
4506
+ invocationTarget: target,
4507
+ invocationTargetInShadowTree: false,
4508
+ shadowAdjustedTarget: target,
4509
+ relatedTarget: null,
4510
+ touchTargets: [],
4511
+ rootOfClosedTree: false,
4512
+ slotInClosedTree: false
4513
+ }
4514
+ ];
4515
+ notifyWildcardListeners(dispatchState.type, event);
4516
+ const list = listeners.get(dispatchState.type);
4517
+ const snapshot = list ? list.slice() : [];
4518
+ invokeListeners(dispatchState.type, event, "capturing", snapshot);
4519
+ invokeListeners(dispatchState.type, event, "bubbling", snapshot);
4520
+ dispatchState.eventPhase = event.NONE;
4521
+ dispatchState.currentTarget = null;
4522
+ dispatchState.path = [];
4523
+ dispatchState.dispatchFlag = false;
4524
+ dispatchState.stopPropagationFlag = false;
4525
+ dispatchState.stopImmediatePropagationFlag = false;
4526
+ return !dispatchState.canceledFlag;
4527
+ };
4528
+ const removeEventListener = (type, listener, options2) => {
4529
+ if (!listener)
4530
+ return;
4531
+ const capture = normalizeCaptureOption(options2);
4532
+ const list = listeners.get(type);
4533
+ if (!list)
4534
+ return;
4535
+ for (const record of [...list]) {
4536
+ if (record.original === listener && record.capture === capture) {
4537
+ removeListenerRecord(type, record);
4538
+ }
4539
+ }
4540
+ };
4541
+ const clear = () => {
4542
+ for (const [type, list] of Array.from(listeners.entries())) {
4543
+ for (const record of [...list]) {
4544
+ removeListenerRecord(type, record);
4545
+ }
4546
+ }
4547
+ listeners.clear();
4548
+ for (const record of wildcardListeners) {
4549
+ if (record.signal && record.abortHandler) {
4550
+ record.signal.removeEventListener("abort", record.abortHandler);
4551
+ }
4552
+ }
4553
+ wildcardListeners.clear();
4554
+ };
4555
+ const on = (type, options2) => {
4556
+ return new Observable((observer) => {
4557
+ let opts2;
4558
+ if (typeof options2 === "boolean") {
4559
+ opts2 = { capture: options2 };
4560
+ } else {
4561
+ opts2 = options2 ?? {};
4562
+ }
4563
+ const handler = opts2.handler;
4564
+ const once = opts2.once;
4565
+ const eventHandler = (e) => {
4566
+ let success = false;
4567
+ try {
4568
+ if (handler) {
4569
+ handler(e);
4570
+ }
4571
+ observer.next(e);
4572
+ success = true;
4573
+ } finally {
4574
+ if (once && success) {
4575
+ observer.complete();
4576
+ }
4577
+ }
4578
+ };
4579
+ const errorHandler = (e) => {
4580
+ observer.error(e.detail);
4581
+ };
4582
+ const unsubscribeEvent = addEventListener(type, eventHandler, opts2);
4583
+ let unsubscribeError;
4584
+ if (opts2.receiveError) {
4585
+ unsubscribeError = addEventListener("error", errorHandler, opts2);
4586
+ }
4587
+ return () => {
4588
+ unsubscribeEvent();
4589
+ if (unsubscribeError) {
4590
+ unsubscribeError();
4591
+ }
4592
+ };
4593
+ });
4594
+ };
4595
+ const onceMethod = (type, listener, options2) => {
4596
+ if (typeof options2 === "boolean") {
4597
+ return addEventListener(type, listener, { capture: options2, once: true });
4598
+ }
4599
+ return addEventListener(type, listener, { ...options2 ?? {}, once: true });
4600
+ };
4601
+ const removeAllListeners = (type) => {
4602
+ if (type !== undefined) {
4603
+ const list = listeners.get(type);
4604
+ if (list) {
4605
+ for (const record of [...list]) {
4606
+ removeListenerRecord(type, record);
4607
+ }
4608
+ listeners.delete(type);
4609
+ }
4610
+ } else {
4611
+ for (const [eventType, list] of Array.from(listeners.entries())) {
4612
+ for (const record of [...list]) {
4613
+ removeListenerRecord(eventType, record);
4614
+ }
4615
+ }
4616
+ listeners.clear();
4617
+ for (const record of wildcardListeners) {
4618
+ if (record.signal && record.abortHandler) {
4619
+ record.signal.removeEventListener("abort", record.abortHandler);
4620
+ }
4621
+ }
4622
+ wildcardListeners.clear();
4623
+ }
4624
+ };
4625
+ const pipe = (target2, mapFn) => {
4626
+ if (isCompleted) {
4627
+ return () => {};
4628
+ }
4629
+ const unsubscribe2 = addWildcardListener("*", (event) => {
4630
+ if (mapFn) {
4631
+ const mapped = mapFn(createEvent(event.originalType, event.detail, {
4632
+ target: target2,
4633
+ currentTarget: target2,
4634
+ eventPhase: 2,
4635
+ bubbles: event.bubbles,
4636
+ cancelable: event.cancelable,
4637
+ composed: event.composed
4638
+ }));
4639
+ if (mapped !== null) {
4640
+ target2.dispatchEvent(mapped);
4641
+ }
4642
+ } else {
4643
+ target2.dispatchEvent({
4644
+ type: event.originalType,
4645
+ detail: event.detail
4646
+ });
4647
+ }
4648
+ });
4649
+ const completionUnsub = () => {
4650
+ unsubscribe2();
4651
+ };
4652
+ completionCallbacks.add(completionUnsub);
4653
+ return () => {
4654
+ completionCallbacks.delete(completionUnsub);
4655
+ unsubscribe2();
4656
+ };
4657
+ };
4658
+ const complete2 = () => {
4659
+ if (isCompleted)
4660
+ return;
4661
+ isCompleted = true;
4662
+ for (const cb of completionCallbacks) {
4663
+ try {
4664
+ cb();
4665
+ } catch (err) {
4666
+ try {
4667
+ handleListenerError("complete", err);
4668
+ } catch {}
4669
+ }
4670
+ }
4671
+ completionCallbacks.clear();
4672
+ for (const [eventType, list] of Array.from(listeners.entries())) {
4673
+ for (const record of [...list]) {
4674
+ removeListenerRecord(eventType, record);
4675
+ }
4676
+ }
4677
+ listeners.clear();
4678
+ for (const record of wildcardListeners) {
4679
+ if (record.signal && record.abortHandler) {
4680
+ record.signal.removeEventListener("abort", record.abortHandler);
4681
+ }
4682
+ }
4683
+ wildcardListeners.clear();
4684
+ };
4685
+ const subscribe = (type, observerOrNext, error2, completeHandler) => {
4686
+ let observer;
4687
+ if (typeof observerOrNext === "function") {
4688
+ observer = {
4689
+ next: observerOrNext,
4690
+ error: error2,
4691
+ complete: completeHandler
4692
+ };
4693
+ } else {
4694
+ observer = observerOrNext ?? {};
4695
+ }
4696
+ let closed = false;
4697
+ if (isCompleted) {
4698
+ if (observer.complete) {
4699
+ try {
4700
+ observer.complete();
4701
+ } catch {}
4702
+ }
4703
+ return {
4704
+ unsubscribe: () => {
4705
+ closed = true;
4706
+ },
4707
+ get closed() {
4708
+ return closed || isCompleted;
4709
+ }
4710
+ };
4711
+ }
4712
+ const unsub = addEventListener(type, (event) => {
4713
+ if (closed)
4714
+ return;
4715
+ if (observer.next) {
4716
+ try {
4717
+ observer.next(event);
4718
+ } catch (err) {
4719
+ if (observer.error) {
4720
+ try {
4721
+ observer.error(err);
4722
+ } catch {}
4723
+ }
4724
+ }
4725
+ }
4726
+ });
4727
+ const onComplete = () => {
4728
+ if (closed)
4729
+ return;
4730
+ closed = true;
4731
+ if (observer.complete) {
4732
+ try {
4733
+ observer.complete();
4734
+ } catch {}
4735
+ }
4736
+ };
4737
+ completionCallbacks.add(onComplete);
4738
+ return {
4739
+ unsubscribe: () => {
4740
+ if (closed)
4741
+ return;
4742
+ closed = true;
4743
+ completionCallbacks.delete(onComplete);
4744
+ unsub();
4745
+ },
4746
+ get closed() {
4747
+ return closed || isCompleted;
4748
+ }
4749
+ };
4750
+ };
4751
+ const toObservable = () => {
4752
+ return new Observable((observer) => {
4753
+ if (isCompleted) {
4754
+ observer.complete();
4755
+ return;
4756
+ }
4757
+ const wildcardListener = (event) => {
4758
+ observer.next(createEvent(event.originalType, event.detail, {
4759
+ target,
4760
+ currentTarget: target,
4761
+ eventPhase: 2,
4762
+ bubbles: event.bubbles,
4763
+ cancelable: event.cancelable,
4764
+ composed: event.composed
4765
+ }));
4766
+ };
4767
+ const unsubscribe2 = addWildcardListener("*", wildcardListener);
4768
+ const onComplete = () => {
4769
+ observer.complete();
4770
+ };
4771
+ completionCallbacks.add(onComplete);
4772
+ return () => {
4773
+ unsubscribe2();
4774
+ completionCallbacks.delete(onComplete);
4775
+ };
4776
+ });
4777
+ };
4778
+ function events(type, options2) {
4779
+ if (isCompleted) {
4780
+ return {
4781
+ [Symbol.asyncIterator]() {
4782
+ return this;
4783
+ },
4784
+ next() {
4785
+ return Promise.resolve({
4786
+ value: undefined,
4787
+ done: true
4788
+ });
4789
+ },
4790
+ return() {
4791
+ return Promise.resolve({
4792
+ value: undefined,
4793
+ done: true
4794
+ });
4795
+ }
4796
+ };
4797
+ }
4798
+ const signal = options2?.signal;
4799
+ const bufferSize = options2?.bufferSize ?? Infinity;
4800
+ const overflowStrategy = options2?.overflowStrategy ?? "drop-oldest";
4801
+ const buffer = [];
4802
+ let resolve = null;
4803
+ let done = false;
4804
+ let hasOverflow = false;
4805
+ let onAbort = null;
4806
+ const cleanupAbortListener = () => {
4807
+ if (signal && onAbort) {
4808
+ signal.removeEventListener("abort", onAbort);
4809
+ }
4810
+ };
4811
+ const unsub = addEventListener(type, (event) => {
4812
+ if (done)
4813
+ return;
4814
+ const typedEvent = event;
4815
+ if (resolve) {
4816
+ const r = resolve;
4817
+ resolve = null;
4818
+ r({ value: typedEvent, done: false });
4819
+ } else {
4820
+ if (buffer.length >= bufferSize && bufferSize !== Infinity) {
4821
+ switch (overflowStrategy) {
4822
+ case "drop-oldest":
4823
+ buffer.shift();
4824
+ buffer.push(typedEvent);
4825
+ break;
4826
+ case "drop-latest":
4827
+ break;
4828
+ case "throw":
4829
+ unsub();
4830
+ completionCallbacks.delete(onComplete);
4831
+ done = true;
4832
+ hasOverflow = true;
4833
+ cleanupAbortListener();
4834
+ return;
4835
+ }
4836
+ } else {
4837
+ buffer.push(typedEvent);
4838
+ }
4839
+ }
4840
+ });
4841
+ const onComplete = () => {
4842
+ done = true;
4843
+ cleanupAbortListener();
4844
+ if (resolve) {
4845
+ const r = resolve;
4846
+ resolve = null;
4847
+ r({ value: undefined, done: true });
4848
+ }
4849
+ };
4850
+ completionCallbacks.add(onComplete);
4851
+ if (signal) {
4852
+ onAbort = () => {
4853
+ done = true;
4854
+ completionCallbacks.delete(onComplete);
4855
+ unsub();
4856
+ if (resolve) {
4857
+ const r = resolve;
4858
+ resolve = null;
4859
+ r({ value: undefined, done: true });
4860
+ }
4861
+ };
4862
+ signal.addEventListener("abort", onAbort, { once: true });
4863
+ if (signal.aborted)
4864
+ onAbort();
4865
+ }
4866
+ const iterator = {
4867
+ [Symbol.asyncIterator]() {
4868
+ return this;
4869
+ },
4870
+ async next() {
4871
+ if (buffer.length > 0) {
4872
+ return { value: buffer.shift(), done: false };
4873
+ }
4874
+ if (resolve !== null) {
4875
+ return Promise.reject(new Error("Concurrent calls to next() are not supported on this async iterator"));
4876
+ }
4877
+ return new Promise((_resolve, _reject) => {
4878
+ if (hasOverflow) {
4879
+ hasOverflow = false;
4880
+ _reject(new BufferOverflowError(type, bufferSize));
4881
+ return;
4882
+ }
4883
+ if (done) {
4884
+ _resolve({
4885
+ value: undefined,
4886
+ done: true
4887
+ });
4888
+ return;
4889
+ }
4890
+ resolve = _resolve;
4891
+ });
4892
+ },
4893
+ return() {
4894
+ if (resolve) {
4895
+ const r = resolve;
4896
+ resolve = null;
4897
+ r({ value: undefined, done: true });
4898
+ }
4899
+ done = true;
4900
+ completionCallbacks.delete(onComplete);
4901
+ unsub();
4902
+ cleanupAbortListener();
4903
+ return Promise.resolve({
4904
+ value: undefined,
4905
+ done: true
4906
+ });
4907
+ }
4908
+ };
4909
+ return iterator;
4910
+ }
4911
+ const target = {
4912
+ addEventListener,
4913
+ removeEventListener,
4914
+ dispatchEvent,
4915
+ clear,
4916
+ on,
4917
+ once: onceMethod,
4918
+ removeAllListeners,
4919
+ pipe,
4920
+ addWildcardListener,
4921
+ removeWildcardListener,
4922
+ complete: complete2,
4923
+ get completed() {
4924
+ return isCompleted;
4925
+ },
4926
+ subscribe,
4927
+ toObservable,
4928
+ events
4929
+ };
4930
+ target[SymbolObservable] = () => {
4931
+ return toObservable();
4932
+ };
4933
+ return target;
4934
+ }
4935
+
4936
+ class EventEmission {
4937
+ #target;
4938
+ constructor() {
4939
+ this.#target = createEventTarget();
4940
+ }
4941
+ addEventListener(type, listener, options2) {
4942
+ return this.#target.addEventListener(type, listener, options2);
4943
+ }
4944
+ removeEventListener(type, listener, options2) {
4945
+ this.#target.removeEventListener(type, listener, options2);
4946
+ }
4947
+ dispatchEvent(event) {
4948
+ return this.#target.dispatchEvent(event);
4949
+ }
4950
+ on(type, options2) {
4951
+ return this.#target.on(type, options2);
4952
+ }
4953
+ once(type, listener, options2) {
4954
+ return this.#target.once(type, listener, options2);
4955
+ }
4956
+ removeAllListeners(type) {
4957
+ this.#target.removeAllListeners(type);
4958
+ }
4959
+ clear() {
4960
+ this.#target.clear();
4961
+ }
4962
+ pipe(target, mapFn) {
4963
+ return this.#target.pipe(target, mapFn);
4964
+ }
4965
+ addWildcardListener(pattern, listener, options2) {
4966
+ return this.#target.addWildcardListener(pattern, listener, options2);
4967
+ }
4968
+ removeWildcardListener(pattern, listener) {
4969
+ this.#target.removeWildcardListener(pattern, listener);
4970
+ }
4971
+ subscribe(typeOrObserver, observerOrNext, error2, completeHandler) {
4972
+ if (typeof typeOrObserver === "string") {
4973
+ return this.#target.subscribe(typeOrObserver, observerOrNext, error2, completeHandler);
4974
+ }
4975
+ if (typeof typeOrObserver === "function") {
4976
+ return this.#target.toObservable().subscribe(typeOrObserver);
4977
+ }
4978
+ if (typeof typeOrObserver === "object" && typeOrObserver !== null) {
4979
+ const maybeObserver = typeOrObserver;
4980
+ if (typeof maybeObserver.next === "function" || typeof maybeObserver.error === "function" || typeof maybeObserver.complete === "function") {
4981
+ return this.#target.toObservable().subscribe(typeOrObserver);
4982
+ }
4983
+ return this.#target.toObservable().subscribe({});
4984
+ }
4985
+ throw new Error("subscribe() requires a string event type, callback function, or observer object");
4986
+ }
4987
+ toObservable() {
4988
+ return this.#target.toObservable();
4989
+ }
4990
+ [SymbolObservable]() {
4991
+ return this.toObservable();
4992
+ }
4993
+ complete() {
4994
+ this.#target.complete();
4995
+ }
4996
+ get completed() {
4997
+ return this.#target.completed;
4998
+ }
4999
+ events(type, options2) {
5000
+ return this.#target.events(type, options2);
5001
+ }
5002
+ }
5003
+
5004
+ // src/errors.ts
5005
+ class ConversationalistError extends Error {
5006
+ code;
5007
+ context;
5008
+ cause;
5009
+ constructor(code, message, options2) {
5010
+ super(message);
5011
+ this.name = "ConversationalistError";
5012
+ this.code = code;
5013
+ this.context = options2?.context;
5014
+ this.cause = options2?.cause;
5015
+ if (Error.captureStackTrace) {
5016
+ Error.captureStackTrace(this, ConversationalistError);
5017
+ }
5018
+ }
5019
+ toDetailedString() {
5020
+ const parts = [`[${this.code}] ${this.message}`];
5021
+ if (this.context && Object.keys(this.context).length > 0) {
5022
+ parts.push(`Context: ${JSON.stringify(this.context, null, 2)}`);
5023
+ }
5024
+ if (this.cause) {
5025
+ parts.push(`Caused by: ${this.cause.message}`);
5026
+ }
5027
+ return parts.join(`
5028
+ `);
5029
+ }
5030
+ }
5031
+ function createInvalidPositionError(expected, actual) {
5032
+ return new ConversationalistError("error:invalid-position", `invalid position: expected ${expected}, got ${actual}`, { context: { expected, actual } });
5033
+ }
5034
+ function createInvalidToolReferenceError(callId) {
5035
+ return new ConversationalistError("error:invalid-tool-reference", `tool result references non-existent tool-use: ${callId}`, { context: { callId } });
5036
+ }
5037
+ function createSerializationError(message, cause) {
5038
+ return new ConversationalistError("error:serialization", message, { cause });
5039
+ }
5040
+ function createValidationError(message, context, cause) {
5041
+ return new ConversationalistError("error:validation", message, { context, cause });
5042
+ }
5043
+ function createIntegrityError(message, context) {
5044
+ return new ConversationalistError("error:integrity", message, { context });
5045
+ }
5046
+
5047
+ // src/schemas.ts
5048
+ import { z } from "zod";
5049
+ var isPlainObject = (value) => {
5050
+ if (!value || typeof value !== "object")
5051
+ return false;
5052
+ const prototype = Reflect.getPrototypeOf(value);
5053
+ return prototype === Object.prototype || prototype === null;
5054
+ };
5055
+ function toMultiModalContent(value) {
5056
+ const result = { type: value.type };
5057
+ if (value.text !== undefined)
5058
+ result.text = value.text;
5059
+ if (value.url !== undefined)
5060
+ result.url = value.url;
5061
+ if (value.mimeType !== undefined)
5062
+ result.mimeType = value.mimeType;
5063
+ return result;
5064
+ }
5065
+ var jsonValueSchema = z.lazy(() => {
5066
+ const jsonObjectSchema = z.preprocess((value, ctx) => {
5067
+ if (!isPlainObject(value)) {
5068
+ ctx.addIssue({
5069
+ code: z.ZodIssueCode.custom,
5070
+ message: "expected a plain object"
5071
+ });
5072
+ return z.NEVER;
5073
+ }
5074
+ return value;
5075
+ }, z.record(z.string(), jsonValueSchema));
5076
+ return z.union([
5077
+ z.string(),
5078
+ z.number().refine((value) => Number.isFinite(value), {
5079
+ message: "expected a finite number"
5080
+ }),
5081
+ z.boolean(),
5082
+ z.null(),
5083
+ z.array(jsonValueSchema),
5084
+ jsonObjectSchema
5085
+ ]);
5086
+ });
5087
+ var multiModalContentSchema = z.discriminatedUnion("type", [
5088
+ z.object({
5089
+ type: z.literal("text"),
5090
+ text: z.string()
5091
+ }),
5092
+ z.object({
5093
+ type: z.literal("image"),
5094
+ url: z.string().url(),
5095
+ mimeType: z.string().optional(),
5096
+ text: z.string().optional()
5097
+ })
5098
+ ]).transform(toMultiModalContent);
5099
+ var messageRoleSchema = z.enum([
5100
+ "user",
5101
+ "assistant",
5102
+ "system",
5103
+ "developer",
5104
+ "tool-use",
5105
+ "tool-result",
5106
+ "snapshot"
5107
+ ]);
5108
+ var toolCallSchema = z.object({
5109
+ id: z.string(),
5110
+ name: z.string(),
5111
+ arguments: jsonValueSchema
5112
+ }).strict();
5113
+ var toolResultSchema = z.object({
5114
+ callId: z.string(),
5115
+ outcome: z.enum(["success", "error"]),
5116
+ content: jsonValueSchema
5117
+ }).strict();
5118
+ var tokenUsageSchema = z.object({
5119
+ prompt: z.number().int().min(0),
5120
+ completion: z.number().int().min(0),
5121
+ total: z.number().int().min(0)
5122
+ });
5123
+ var messageInputSchema = z.object({
5124
+ role: messageRoleSchema,
5125
+ content: z.union([z.string(), z.array(multiModalContentSchema)]),
5126
+ metadata: z.record(z.string(), jsonValueSchema).optional(),
5127
+ hidden: z.boolean().optional(),
5128
+ toolCall: toolCallSchema.optional(),
5129
+ toolResult: toolResultSchema.optional(),
5130
+ tokenUsage: tokenUsageSchema.optional(),
5131
+ goalCompleted: z.boolean().optional()
5132
+ }).strict();
5133
+ var messageSchema = z.object({
5134
+ id: z.string(),
5135
+ role: messageRoleSchema,
5136
+ content: z.union([z.string(), z.array(multiModalContentSchema)]),
5137
+ position: z.number().int().min(0),
5138
+ createdAt: z.string(),
5139
+ metadata: z.record(z.string(), jsonValueSchema),
5140
+ hidden: z.boolean(),
5141
+ toolCall: toolCallSchema.optional(),
5142
+ toolResult: toolResultSchema.optional(),
5143
+ tokenUsage: tokenUsageSchema.optional(),
5144
+ goalCompleted: z.boolean().optional()
5145
+ }).strict();
5146
+ var conversationStatusSchema = z.enum([
5147
+ "active",
5148
+ "archived",
5149
+ "deleted"
5150
+ ]);
5151
+ var conversationShape = {
5152
+ schemaVersion: z.number().int().min(1),
5153
+ id: z.string(),
5154
+ title: z.string().optional(),
5155
+ status: conversationStatusSchema,
5156
+ metadata: z.record(z.string(), jsonValueSchema),
5157
+ ids: z.array(z.string()),
5158
+ messages: z.record(z.string(), messageSchema),
5159
+ createdAt: z.string(),
5160
+ updatedAt: z.string()
5161
+ };
5162
+ var conversationSchema = z.object(conversationShape).strict();
5163
+
5164
+ // src/conversation/integrity.ts
5165
+ function validateConversationIntegrity(conversation) {
5166
+ const issues = [];
5167
+ const seenIds = new Set;
5168
+ conversation.ids.forEach((id, index) => {
5169
+ if (seenIds.has(id)) {
5170
+ issues.push({
5171
+ code: "integrity:duplicate-message-id",
5172
+ message: `duplicate message id in ids: ${id}`,
5173
+ data: { id, position: index }
5174
+ });
5175
+ } else {
5176
+ seenIds.add(id);
5177
+ }
5178
+ if (!conversation.messages[id]) {
5179
+ issues.push({
5180
+ code: "integrity:missing-message",
5181
+ message: `missing message for id ${id}`,
5182
+ data: { id, position: index }
5183
+ });
5184
+ }
5185
+ });
5186
+ for (const id of Object.keys(conversation.messages)) {
5187
+ if (!seenIds.has(id)) {
5188
+ issues.push({
5189
+ code: "integrity:unlisted-message",
5190
+ message: `message ${id} is not listed in ids`,
5191
+ data: { id }
5192
+ });
5193
+ }
5194
+ }
5195
+ const toolUses = new Map;
5196
+ conversation.ids.forEach((id, index) => {
5197
+ const message = conversation.messages[id];
5198
+ if (!message)
5199
+ return;
5200
+ if (message.role === "tool-use" && message.toolCall) {
5201
+ if (toolUses.has(message.toolCall.id)) {
5202
+ issues.push({
5203
+ code: "integrity:duplicate-tool-call",
5204
+ message: `duplicate toolCall.id ${message.toolCall.id}`,
5205
+ data: { toolCallId: message.toolCall.id, messageId: message.id }
5206
+ });
5207
+ } else {
5208
+ toolUses.set(message.toolCall.id, { position: index, messageId: message.id });
5209
+ }
5210
+ }
5211
+ });
5212
+ conversation.ids.forEach((id, index) => {
5213
+ const message = conversation.messages[id];
5214
+ if (!message)
5215
+ return;
5216
+ if (message.role === "tool-result" && message.toolResult) {
5217
+ const toolUse = toolUses.get(message.toolResult.callId);
5218
+ if (!toolUse) {
5219
+ issues.push({
5220
+ code: "integrity:orphan-tool-result",
5221
+ message: `tool-result references missing tool-use ${message.toolResult.callId}`,
5222
+ data: { callId: message.toolResult.callId, messageId: message.id }
5223
+ });
5224
+ } else if (toolUse.position >= index) {
5225
+ issues.push({
5226
+ code: "integrity:tool-result-before-call",
5227
+ message: `tool-result ${message.toolResult.callId} occurs before tool-use`,
5228
+ data: {
5229
+ callId: message.toolResult.callId,
5230
+ messageId: message.id,
5231
+ toolUseMessageId: toolUse.messageId
5232
+ }
5233
+ });
5234
+ }
5235
+ }
5236
+ });
5237
+ return issues;
5238
+ }
5239
+ function assertConversationIntegrity(conversation) {
5240
+ const issues = validateConversationIntegrity(conversation);
5241
+ if (issues.length === 0)
5242
+ return;
5243
+ throw createIntegrityError("conversation integrity check failed", { issues });
5244
+ }
5245
+
5246
+ // src/conversation/validation.ts
5247
+ function assertConversationSafe(conversation) {
5248
+ const parsed = conversationSchema.safeParse(conversation);
5249
+ if (!parsed.success) {
5250
+ throw createValidationError("conversation failed schema validation", {
5251
+ issues: parsed.error.issues
5252
+ });
5253
+ }
5254
+ assertConversationIntegrity(conversation);
5255
+ }
5256
+ function ensureConversationSafe(conversation) {
5257
+ assertConversationSafe(conversation);
5258
+ return conversation;
5259
+ }
5260
+
3494
5261
  // src/utilities/content.ts
3495
5262
  function normalizeContent(content) {
3496
5263
  if (content === undefined)
@@ -3655,6 +5422,92 @@ var cloneMessageWithPosition = (message, position, content) => {
3655
5422
  }
3656
5423
  return createMessage(baseMessage);
3657
5424
  };
5425
+ var createMessageBlock = (message, estimator) => ({
5426
+ messages: [message],
5427
+ minPosition: message.position,
5428
+ maxPosition: message.position,
5429
+ tokenCount: estimator(message)
5430
+ });
5431
+ var buildMessageBlocks = (messages, estimator, preserveToolPairs) => {
5432
+ if (!preserveToolPairs) {
5433
+ const blocks2 = messages.map((message) => createMessageBlock(message, estimator));
5434
+ const messageToBlock2 = new Map;
5435
+ for (const block of blocks2) {
5436
+ const message = block.messages[0];
5437
+ if (message) {
5438
+ messageToBlock2.set(message.id, block);
5439
+ }
5440
+ }
5441
+ return { blocks: blocks2, messageToBlock: messageToBlock2 };
5442
+ }
5443
+ const blocks = [];
5444
+ const toolUses = new Map;
5445
+ for (const message of messages) {
5446
+ if (message.role === "tool-use" && message.toolCall) {
5447
+ const block = createMessageBlock(message, estimator);
5448
+ toolUses.set(message.toolCall.id, block);
5449
+ blocks.push(block);
5450
+ continue;
5451
+ }
5452
+ if (message.role === "tool-result" && message.toolResult) {
5453
+ const existing = toolUses.get(message.toolResult.callId);
5454
+ if (existing) {
5455
+ existing.messages.push(message);
5456
+ existing.maxPosition = Math.max(existing.maxPosition, message.position);
5457
+ existing.tokenCount += estimator(message);
5458
+ continue;
5459
+ }
5460
+ const orphanBlock = createMessageBlock(message, estimator);
5461
+ orphanBlock.orphanToolResult = true;
5462
+ blocks.push(orphanBlock);
5463
+ continue;
5464
+ }
5465
+ blocks.push(createMessageBlock(message, estimator));
5466
+ }
5467
+ const filteredBlocks = blocks.filter((block) => !block.orphanToolResult);
5468
+ const messageToBlock = new Map;
5469
+ for (const block of filteredBlocks) {
5470
+ for (const message of block.messages) {
5471
+ messageToBlock.set(message.id, block);
5472
+ }
5473
+ }
5474
+ return { blocks: filteredBlocks, messageToBlock };
5475
+ };
5476
+ var collectBlocksForMessages = (messages, messageToBlock) => {
5477
+ const blocks = [];
5478
+ const seen = new Set;
5479
+ for (const message of messages) {
5480
+ const block = messageToBlock.get(message.id);
5481
+ if (block && !seen.has(block)) {
5482
+ seen.add(block);
5483
+ blocks.push(block);
5484
+ }
5485
+ }
5486
+ return blocks;
5487
+ };
5488
+ var collectMessagesFromBlocks = (blocks) => {
5489
+ const messages = [];
5490
+ const seen = new Set;
5491
+ for (const block of blocks) {
5492
+ for (const message of block.messages) {
5493
+ if (!seen.has(message.id)) {
5494
+ seen.add(message.id);
5495
+ messages.push(message);
5496
+ }
5497
+ }
5498
+ }
5499
+ messages.sort((a, b) => a.position - b.position);
5500
+ return messages;
5501
+ };
5502
+ var ensureTruncationSafe = (conversation, preserveToolPairs, operation) => {
5503
+ try {
5504
+ return ensureConversationSafe(conversation);
5505
+ } catch (error2) {
5506
+ if (!preserveToolPairs && error2 instanceof ConversationalistError && error2.code === "error:integrity")
5507
+ throw createIntegrityError(`${operation} produced invalid tool linkage; use preserveToolPairs: true to keep tool interactions intact`, { preserveToolPairs, issues: error2.context?.["issues"] });
5508
+ throw error2;
5509
+ }
5510
+ };
3658
5511
  function estimateConversationTokens(conversation, estimateTokens, environment) {
3659
5512
  let estimator = estimateTokens;
3660
5513
  let env = environment;
@@ -3667,6 +5520,7 @@ function estimateConversationTokens(conversation, estimateTokens, environment) {
3667
5520
  return getOrderedMessages(conversation).reduce((total, message) => total + finalEstimator(message), 0);
3668
5521
  }
3669
5522
  function truncateToTokenLimit(conversation, maxTokens, optionsOrEstimator, environment) {
5523
+ assertConversationSafe(conversation);
3670
5524
  let options2 = {};
3671
5525
  let env = environment;
3672
5526
  if (typeof optionsOrEstimator === "function") {
@@ -3688,54 +5542,56 @@ function truncateToTokenLimit(conversation, maxTokens, optionsOrEstimator, envir
3688
5542
  const estimator = options2.estimateTokens ?? resolvedEnvironment.estimateTokens;
3689
5543
  const preserveSystem = options2.preserveSystemMessages ?? true;
3690
5544
  const preserveLastN = options2.preserveLastN ?? 0;
5545
+ const preserveToolPairs = options2.preserveToolPairs ?? true;
3691
5546
  const currentTokens = estimateConversationTokens(conversation, estimator, resolvedEnvironment);
3692
5547
  if (currentTokens <= maxTokens) {
3693
5548
  return conversation;
3694
5549
  }
3695
5550
  const now = resolvedEnvironment.now();
3696
5551
  const orderedMessages = getOrderedMessages(conversation);
5552
+ const { blocks, messageToBlock } = buildMessageBlocks(orderedMessages, estimator, preserveToolPairs);
3697
5553
  const systemMessages = preserveSystem ? orderedMessages.filter((m) => m.role === "system") : [];
3698
5554
  const nonSystemMessages = orderedMessages.filter((m) => m.role !== "system");
3699
5555
  const protectedMessages = preserveLastN > 0 ? nonSystemMessages.slice(-preserveLastN) : [];
3700
- const removableMessages = preserveLastN > 0 ? nonSystemMessages.slice(0, -preserveLastN) : nonSystemMessages;
3701
- const systemTokens = systemMessages.reduce((sum, m) => sum + estimator(m), 0);
3702
- const protectedTokens = protectedMessages.reduce((sum, m) => sum + estimator(m), 0);
5556
+ const systemBlocks = collectBlocksForMessages(systemMessages, messageToBlock);
5557
+ const protectedBlocks = collectBlocksForMessages(protectedMessages, messageToBlock);
5558
+ const lockedBlocks = new Set([...systemBlocks, ...protectedBlocks]);
5559
+ const removableBlocks = blocks.filter((block) => !lockedBlocks.has(block));
5560
+ const systemTokens = systemBlocks.reduce((sum, block) => sum + block.tokenCount, 0);
5561
+ const protectedTokens = protectedBlocks.reduce((sum, block) => sum + block.tokenCount, 0);
3703
5562
  const availableTokens = maxTokens - systemTokens - protectedTokens;
5563
+ let selectedBlocks = [];
3704
5564
  if (availableTokens <= 0) {
3705
- const allMessages2 = [...systemMessages, ...protectedMessages];
3706
- const renumbered2 = allMessages2.map((message, index) => cloneMessageWithPosition(message, index, copyContent(message.content)));
3707
- return toReadonly({
3708
- ...conversation,
3709
- ids: renumbered2.map((message) => message.id),
3710
- messages: toIdRecord(renumbered2),
3711
- updatedAt: now
3712
- });
3713
- }
3714
- const keptRemovable = [];
3715
- let usedTokens = 0;
3716
- for (let i = removableMessages.length - 1;i >= 0; i--) {
3717
- const message = removableMessages[i];
3718
- const messageTokens = estimator(message);
3719
- if (usedTokens + messageTokens <= availableTokens) {
3720
- keptRemovable.unshift(message);
3721
- usedTokens += messageTokens;
3722
- } else {
3723
- break;
5565
+ selectedBlocks = [...systemBlocks, ...protectedBlocks];
5566
+ } else {
5567
+ const sortedRemovable = [...removableBlocks].sort((a, b) => a.maxPosition - b.maxPosition);
5568
+ const keptRemovable = [];
5569
+ let usedTokens = 0;
5570
+ for (let i = sortedRemovable.length - 1;i >= 0; i--) {
5571
+ const block = sortedRemovable[i];
5572
+ if (usedTokens + block.tokenCount <= availableTokens) {
5573
+ keptRemovable.unshift(block);
5574
+ usedTokens += block.tokenCount;
5575
+ } else {
5576
+ break;
5577
+ }
3724
5578
  }
5579
+ selectedBlocks = [...systemBlocks, ...keptRemovable, ...protectedBlocks];
3725
5580
  }
3726
- const allMessages = [...systemMessages, ...keptRemovable, ...protectedMessages];
3727
- allMessages.sort((a, b) => a.position - b.position);
5581
+ const allMessages = collectMessagesFromBlocks(selectedBlocks);
3728
5582
  const renumbered = allMessages.map((message, index) => cloneMessageWithPosition(message, index, copyContent(message.content)));
3729
- return toReadonly({
5583
+ const next2 = toReadonly({
3730
5584
  ...conversation,
3731
5585
  ids: renumbered.map((message) => message.id),
3732
5586
  messages: toIdRecord(renumbered),
3733
5587
  updatedAt: now
3734
5588
  });
5589
+ return ensureTruncationSafe(next2, preserveToolPairs, "truncateToTokenLimit");
3735
5590
  }
3736
5591
  function getRecentMessages(conversation, count, options2) {
3737
5592
  const includeHidden = options2?.includeHidden ?? false;
3738
5593
  const includeSystem = options2?.includeSystem ?? false;
5594
+ const preserveToolPairs = options2?.preserveToolPairs ?? true;
3739
5595
  const filtered = getOrderedMessages(conversation).filter((m) => {
3740
5596
  if (!includeHidden && m.hidden)
3741
5597
  return false;
@@ -3743,66 +5599,58 @@ function getRecentMessages(conversation, count, options2) {
3743
5599
  return false;
3744
5600
  return true;
3745
5601
  });
3746
- return filtered.slice(-count);
5602
+ if (!preserveToolPairs) {
5603
+ return filtered.slice(-count);
5604
+ }
5605
+ const { messageToBlock } = buildMessageBlocks(filtered, () => 0, preserveToolPairs);
5606
+ const tail = filtered.slice(-count);
5607
+ const blocks = collectBlocksForMessages(tail, messageToBlock);
5608
+ return collectMessagesFromBlocks(blocks);
3747
5609
  }
3748
5610
  function truncateFromPosition(conversation, position, options2, environment) {
5611
+ assertConversationSafe(conversation);
3749
5612
  const preserveSystem = options2?.preserveSystemMessages ?? true;
5613
+ const preserveToolPairs = options2?.preserveToolPairs ?? true;
3750
5614
  const resolvedEnvironment = resolveConversationEnvironment(environment);
3751
5615
  const now = resolvedEnvironment.now();
3752
5616
  const ordered = getOrderedMessages(conversation);
5617
+ const { messageToBlock } = buildMessageBlocks(ordered, () => 0, preserveToolPairs);
3753
5618
  const systemMessages = preserveSystem ? ordered.filter((m) => m.role === "system" && m.position < position) : [];
3754
5619
  const keptMessages = ordered.filter((m) => m.position >= position);
3755
- const allMessages = [...systemMessages, ...keptMessages];
5620
+ const systemBlocks = collectBlocksForMessages(systemMessages, messageToBlock);
5621
+ const keptBlocks = collectBlocksForMessages(keptMessages, messageToBlock);
5622
+ const allMessages = collectMessagesFromBlocks([...systemBlocks, ...keptBlocks]);
3756
5623
  const renumbered = allMessages.map((message, index) => cloneMessageWithPosition(message, index, copyContent(message.content)));
3757
- return toReadonly({
5624
+ const next2 = toReadonly({
3758
5625
  ...conversation,
3759
5626
  ids: renumbered.map((message) => message.id),
3760
5627
  messages: toIdRecord(renumbered),
3761
5628
  updatedAt: now
3762
5629
  });
3763
- }
3764
-
3765
- // src/errors.ts
3766
- class ConversationalistError extends Error {
3767
- code;
3768
- context;
3769
- cause;
3770
- constructor(code, message, options2) {
3771
- super(message);
3772
- this.name = "ConversationalistError";
3773
- this.code = code;
3774
- this.context = options2?.context;
3775
- this.cause = options2?.cause;
3776
- if (Error.captureStackTrace) {
3777
- Error.captureStackTrace(this, ConversationalistError);
3778
- }
3779
- }
3780
- toDetailedString() {
3781
- const parts = [`[${this.code}] ${this.message}`];
3782
- if (this.context && Object.keys(this.context).length > 0) {
3783
- parts.push(`Context: ${JSON.stringify(this.context, null, 2)}`);
3784
- }
3785
- if (this.cause) {
3786
- parts.push(`Caused by: ${this.cause.message}`);
3787
- }
3788
- return parts.join(`
3789
- `);
3790
- }
3791
- }
3792
- function createInvalidPositionError(expected, actual) {
3793
- return new ConversationalistError("error:invalid-position", `invalid position: expected ${expected}, got ${actual}`, { context: { expected, actual } });
3794
- }
3795
- function createInvalidToolReferenceError(callId) {
3796
- return new ConversationalistError("error:invalid-tool-reference", `tool result references non-existent tool-use: ${callId}`, { context: { callId } });
3797
- }
3798
- function createSerializationError(message, cause) {
3799
- return new ConversationalistError("error:serialization", message, { cause });
5630
+ return ensureTruncationSafe(next2, preserveToolPairs, "truncateFromPosition");
3800
5631
  }
3801
5632
 
3802
5633
  // src/types.ts
3803
5634
  var CURRENT_SCHEMA_VERSION = 3;
3804
5635
 
3805
- // src/conversation.ts
5636
+ // src/conversation/create.ts
5637
+ function createConversation(options2, environment) {
5638
+ const resolvedEnvironment = resolveConversationEnvironment(environment);
5639
+ const now = resolvedEnvironment.now();
5640
+ const conv = {
5641
+ schemaVersion: CURRENT_SCHEMA_VERSION,
5642
+ id: options2?.id ?? resolvedEnvironment.randomId(),
5643
+ title: options2?.title,
5644
+ status: options2?.status ?? "active",
5645
+ metadata: { ...options2?.metadata ?? {} },
5646
+ ids: [],
5647
+ messages: {},
5648
+ createdAt: now,
5649
+ updatedAt: now
5650
+ };
5651
+ return ensureConversationSafe(toReadonly(conv));
5652
+ }
5653
+ // src/conversation/tool-tracking.ts
3806
5654
  var buildToolUseIndex = (messages) => messages.reduce((index, message) => {
3807
5655
  if (message.role === "tool-use" && message.toolCall) {
3808
5656
  index.set(message.toolCall.id, { name: message.toolCall.name });
@@ -3810,53 +5658,43 @@ var buildToolUseIndex = (messages) => messages.reduce((index, message) => {
3810
5658
  return index;
3811
5659
  }, new Map);
3812
5660
  var registerToolUse = (index, toolCall) => {
3813
- const next = new Map(index);
3814
- next.set(toolCall.id, { name: toolCall.name });
3815
- return next;
5661
+ const next2 = new Map(index);
5662
+ next2.set(toolCall.id, { name: toolCall.name });
5663
+ return next2;
3816
5664
  };
3817
5665
  var assertToolReference = (index, callId) => {
3818
5666
  if (!index.has(callId)) {
3819
5667
  throw createInvalidToolReferenceError(callId);
3820
5668
  }
3821
5669
  };
5670
+
5671
+ // src/conversation/append.ts
3822
5672
  function partitionAppendArgs(args) {
3823
- if (args.length === 0) {
5673
+ const filtered = args.filter((arg) => arg !== undefined);
5674
+ if (filtered.length === 0) {
3824
5675
  return { inputs: [] };
3825
5676
  }
3826
- const last = args[args.length - 1];
5677
+ const last = filtered[filtered.length - 1];
3827
5678
  if (isConversationEnvironmentParameter(last)) {
3828
5679
  return {
3829
- inputs: args.slice(0, -1),
5680
+ inputs: filtered.slice(0, -1),
3830
5681
  environment: last
3831
5682
  };
3832
5683
  }
3833
- return { inputs: args };
3834
- }
3835
- function createConversation(options2, environment) {
3836
- const resolvedEnvironment = resolveConversationEnvironment(environment);
3837
- const now = resolvedEnvironment.now();
3838
- const conv = {
3839
- schemaVersion: CURRENT_SCHEMA_VERSION,
3840
- id: options2?.id ?? resolvedEnvironment.randomId(),
3841
- title: options2?.title,
3842
- status: options2?.status ?? "active",
3843
- metadata: { ...options2?.metadata ?? {} },
3844
- ids: [],
3845
- messages: {},
3846
- createdAt: now,
3847
- updatedAt: now
3848
- };
3849
- return toReadonly(conv);
5684
+ return { inputs: filtered };
3850
5685
  }
3851
5686
  function appendMessages(conversation, ...args) {
5687
+ return appendMessagesInternal(conversation, args, true);
5688
+ }
5689
+ var appendMessagesInternal = (conversation, args, validate) => {
3852
5690
  const { inputs, environment } = partitionAppendArgs(args);
3853
5691
  const resolvedEnvironment = resolveConversationEnvironment(environment);
3854
5692
  const now = resolvedEnvironment.now();
3855
5693
  const startPosition = conversation.ids.length;
3856
- const initialToolUses = buildToolUseIndex(getOrderedMessages(conversation));
5694
+ const initialToolUses = validate ? buildToolUseIndex(getOrderedMessages(conversation)) : new Map;
3857
5695
  const { messages } = inputs.reduce((state, input, index) => {
3858
5696
  const processedInput = resolvedEnvironment.plugins.reduce((acc, plugin) => plugin(acc), input);
3859
- if (processedInput.role === "tool-result" && processedInput.toolResult) {
5697
+ if (validate && processedInput.role === "tool-result" && processedInput.toolResult) {
3860
5698
  assertToolReference(state.toolUses, processedInput.toolResult.callId);
3861
5699
  }
3862
5700
  const normalizedContent = normalizeContent(processedInput.content);
@@ -3883,30 +5721,47 @@ function appendMessages(conversation, ...args) {
3883
5721
  } else {
3884
5722
  message = createMessage(baseMessage);
3885
5723
  }
3886
- const toolUses = processedInput.role === "tool-use" && processedInput.toolCall ? registerToolUse(state.toolUses, processedInput.toolCall) : state.toolUses;
5724
+ let toolUses = state.toolUses;
5725
+ if (processedInput.role === "tool-use" && processedInput.toolCall) {
5726
+ if (validate && state.toolUses.has(processedInput.toolCall.id)) {
5727
+ throw createIntegrityError("duplicate toolCall.id in conversation", {
5728
+ toolCallId: processedInput.toolCall.id,
5729
+ messageId: baseMessage.id
5730
+ });
5731
+ }
5732
+ toolUses = validate ? registerToolUse(state.toolUses, processedInput.toolCall) : state.toolUses;
5733
+ }
3887
5734
  return {
3888
5735
  toolUses,
3889
5736
  messages: [...state.messages, message]
3890
5737
  };
3891
5738
  }, { toolUses: initialToolUses, messages: [] });
3892
5739
  const messageIds = messages.map((message) => message.id);
3893
- const next = {
5740
+ const next2 = {
3894
5741
  ...conversation,
3895
5742
  ids: [...conversation.ids, ...messageIds],
3896
5743
  messages: { ...conversation.messages, ...toIdRecord(messages) },
3897
5744
  updatedAt: now
3898
5745
  };
3899
- return toReadonly(next);
3900
- }
5746
+ const readonly = toReadonly(next2);
5747
+ return validate ? ensureConversationSafe(readonly) : readonly;
5748
+ };
3901
5749
  function appendUserMessage(conversation, content, metadata, environment) {
3902
- return environment ? appendMessages(conversation, { role: "user", content, metadata }, environment) : appendMessages(conversation, { role: "user", content, metadata });
5750
+ const resolvedEnvironment = isConversationEnvironmentParameter(metadata) ? metadata : environment;
5751
+ const resolvedMetadata = isConversationEnvironmentParameter(metadata) ? undefined : metadata;
5752
+ return appendMessages(conversation, { role: "user", content, metadata: resolvedMetadata }, resolvedEnvironment);
3903
5753
  }
3904
5754
  function appendAssistantMessage(conversation, content, metadata, environment) {
3905
- return environment ? appendMessages(conversation, { role: "assistant", content, metadata }, environment) : appendMessages(conversation, { role: "assistant", content, metadata });
5755
+ const resolvedEnvironment = isConversationEnvironmentParameter(metadata) ? metadata : environment;
5756
+ const resolvedMetadata = isConversationEnvironmentParameter(metadata) ? undefined : metadata;
5757
+ return appendMessages(conversation, { role: "assistant", content, metadata: resolvedMetadata }, resolvedEnvironment);
3906
5758
  }
3907
5759
  function appendSystemMessage(conversation, content, metadata, environment) {
3908
- return environment ? appendMessages(conversation, { role: "system", content, metadata }, environment) : appendMessages(conversation, { role: "system", content, metadata });
5760
+ const resolvedEnvironment = isConversationEnvironmentParameter(metadata) ? metadata : environment;
5761
+ const resolvedMetadata = isConversationEnvironmentParameter(metadata) ? undefined : metadata;
5762
+ return appendMessages(conversation, { role: "system", content, metadata: resolvedMetadata }, resolvedEnvironment);
3909
5763
  }
5764
+ // src/conversation/query.ts
3910
5765
  function getMessages(conversation, options2) {
3911
5766
  const includeHidden = options2?.includeHidden ?? false;
3912
5767
  const ordered = getOrderedMessages(conversation);
@@ -3940,6 +5795,7 @@ function getStatistics(conversation) {
3940
5795
  }, { byRole: {}, hidden: 0, withImages: 0 });
3941
5796
  return { total: ordered.length, ...stats };
3942
5797
  }
5798
+ // src/conversation/system-messages.ts
3943
5799
  function hasSystemMessage(conversation) {
3944
5800
  return getOrderedMessages(conversation).some((m) => m.role === "system");
3945
5801
  }
@@ -3950,7 +5806,8 @@ function getSystemMessages(conversation) {
3950
5806
  return getOrderedMessages(conversation).filter((m) => m.role === "system");
3951
5807
  }
3952
5808
  function prependSystemMessage(conversation, content, metadata, environment) {
3953
- const resolvedEnvironment = resolveConversationEnvironment(environment);
5809
+ const resolvedEnvironment = resolveConversationEnvironment(isConversationEnvironmentParameter(metadata) ? metadata : environment);
5810
+ const resolvedMetadata = isConversationEnvironmentParameter(metadata) ? undefined : metadata;
3954
5811
  const now = resolvedEnvironment.now();
3955
5812
  const newMessage = createMessage({
3956
5813
  id: resolvedEnvironment.randomId(),
@@ -3958,7 +5815,7 @@ function prependSystemMessage(conversation, content, metadata, environment) {
3958
5815
  content,
3959
5816
  position: 0,
3960
5817
  createdAt: now,
3961
- metadata: { ...metadata ?? {} },
5818
+ metadata: { ...resolvedMetadata ?? {} },
3962
5819
  hidden: false,
3963
5820
  toolCall: undefined,
3964
5821
  toolResult: undefined,
@@ -3977,20 +5834,21 @@ function prependSystemMessage(conversation, content, metadata, environment) {
3977
5834
  toolResult: message.toolResult,
3978
5835
  tokenUsage: message.tokenUsage
3979
5836
  }));
3980
- return toReadonly({
5837
+ return ensureConversationSafe(toReadonly({
3981
5838
  ...conversation,
3982
5839
  ids: [newMessage.id, ...ordered.map((message) => message.id)],
3983
5840
  messages: toIdRecord([newMessage, ...renumberedMessages]),
3984
5841
  updatedAt: now
3985
- });
5842
+ }));
3986
5843
  }
3987
5844
  function replaceSystemMessage(conversation, content, metadata, environment) {
3988
- const resolvedEnvironment = resolveConversationEnvironment(environment);
5845
+ const resolvedEnvironment = resolveConversationEnvironment(isConversationEnvironmentParameter(metadata) ? metadata : environment);
5846
+ const resolvedMetadata = isConversationEnvironmentParameter(metadata) ? undefined : metadata;
3989
5847
  const now = resolvedEnvironment.now();
3990
5848
  const ordered = getOrderedMessages(conversation);
3991
5849
  const firstSystemIndex = ordered.findIndex((m) => m.role === "system");
3992
5850
  if (firstSystemIndex === -1) {
3993
- return prependSystemMessage(conversation, content, metadata, resolvedEnvironment);
5851
+ return prependSystemMessage(conversation, content, resolvedMetadata, resolvedEnvironment);
3994
5852
  }
3995
5853
  const original = ordered[firstSystemIndex];
3996
5854
  const replaced = createMessage({
@@ -3999,25 +5857,25 @@ function replaceSystemMessage(conversation, content, metadata, environment) {
3999
5857
  content,
4000
5858
  position: original.position,
4001
5859
  createdAt: original.createdAt,
4002
- metadata: { ...metadata ?? original.metadata },
5860
+ metadata: { ...resolvedMetadata ?? original.metadata },
4003
5861
  hidden: original.hidden,
4004
5862
  toolCall: undefined,
4005
5863
  toolResult: undefined,
4006
5864
  tokenUsage: undefined
4007
5865
  });
4008
- const next = {
5866
+ const next2 = {
4009
5867
  ...conversation,
4010
5868
  ids: [...conversation.ids],
4011
5869
  messages: { ...conversation.messages, [replaced.id]: replaced },
4012
5870
  updatedAt: now
4013
5871
  };
4014
- return toReadonly(next);
5872
+ return ensureConversationSafe(toReadonly(next2));
4015
5873
  }
4016
5874
  function collapseSystemMessages(conversation, environment) {
4017
5875
  const ordered = getOrderedMessages(conversation);
4018
5876
  const systemMessages = ordered.filter((m) => m.role === "system");
4019
5877
  if (systemMessages.length <= 1) {
4020
- return conversation;
5878
+ return ensureConversationSafe(conversation);
4021
5879
  }
4022
5880
  const resolvedEnvironment = resolveConversationEnvironment(environment);
4023
5881
  const now = resolvedEnvironment.now();
@@ -4067,15 +5925,48 @@ function collapseSystemMessages(conversation, environment) {
4067
5925
  tokenUsage: message.tokenUsage
4068
5926
  });
4069
5927
  });
4070
- const next = {
5928
+ const next2 = {
4071
5929
  ...conversation,
4072
5930
  ids: renumbered.map((message) => message.id),
4073
5931
  messages: toIdRecord(renumbered),
4074
5932
  updatedAt: now
4075
5933
  };
4076
- return toReadonly(next);
5934
+ return ensureConversationSafe(toReadonly(next2));
5935
+ }
5936
+ // src/utilities/tool-results.ts
5937
+ function copyToolResult(toolResult) {
5938
+ return { ...toolResult };
5939
+ }
5940
+ function redactToolResult(toolResult, placeholder) {
5941
+ return { ...toolResult, content: placeholder };
4077
5942
  }
4078
- function redactMessageAtPosition(conversation, position, placeholder = "[REDACTED]", environment) {
5943
+
5944
+ // src/conversation/modify.ts
5945
+ var isRedactMessageOptions = (value) => {
5946
+ if (!value || typeof value !== "object")
5947
+ return false;
5948
+ const candidate = value;
5949
+ return "placeholder" in candidate || "redactToolArguments" in candidate || "redactToolResults" in candidate || "clearToolMetadata" in candidate;
5950
+ };
5951
+ function redactMessageAtPosition(conversation, position, placeholderOrOptions, environment) {
5952
+ let placeholder = "[REDACTED]";
5953
+ let options2 = {};
5954
+ let env = environment;
5955
+ if (typeof placeholderOrOptions === "string") {
5956
+ placeholder = placeholderOrOptions;
5957
+ } else if (placeholderOrOptions) {
5958
+ if (!environment && isConversationEnvironmentParameter(placeholderOrOptions)) {
5959
+ env = placeholderOrOptions;
5960
+ } else if (isRedactMessageOptions(placeholderOrOptions)) {
5961
+ options2 = placeholderOrOptions;
5962
+ if (options2.placeholder) {
5963
+ placeholder = options2.placeholder;
5964
+ }
5965
+ }
5966
+ }
5967
+ const redactToolArguments = options2.redactToolArguments ?? true;
5968
+ const redactToolResults = options2.redactToolResults ?? true;
5969
+ const clearToolMetadata = options2.clearToolMetadata ?? false;
4079
5970
  if (position < 0 || position >= conversation.ids.length) {
4080
5971
  throw createInvalidPositionError(conversation.ids.length - 1, position);
4081
5972
  }
@@ -4084,6 +5975,22 @@ function redactMessageAtPosition(conversation, position, placeholder = "[REDACTE
4084
5975
  if (!original) {
4085
5976
  throw createInvalidPositionError(conversation.ids.length - 1, position);
4086
5977
  }
5978
+ let toolCall = original.toolCall ? { ...original.toolCall } : undefined;
5979
+ let toolResult = original.toolResult ? { ...original.toolResult } : undefined;
5980
+ if (clearToolMetadata) {
5981
+ toolCall = undefined;
5982
+ toolResult = undefined;
5983
+ } else {
5984
+ if (original.role === "tool-use" && toolCall) {
5985
+ toolCall = {
5986
+ ...toolCall,
5987
+ arguments: redactToolArguments ? placeholder : toolCall.arguments
5988
+ };
5989
+ }
5990
+ if (original.role === "tool-result" && toolResult) {
5991
+ toolResult = redactToolResults ? redactToolResult(toolResult, placeholder) : { ...toolResult };
5992
+ }
5993
+ }
4087
5994
  const redacted = createMessage({
4088
5995
  id: original.id,
4089
5996
  role: original.role,
@@ -4092,82 +5999,74 @@ function redactMessageAtPosition(conversation, position, placeholder = "[REDACTE
4092
5999
  createdAt: original.createdAt,
4093
6000
  metadata: { ...original.metadata },
4094
6001
  hidden: original.hidden,
4095
- toolCall: undefined,
4096
- toolResult: undefined,
4097
- tokenUsage: undefined
6002
+ toolCall,
6003
+ toolResult,
6004
+ tokenUsage: original.tokenUsage ? { ...original.tokenUsage } : undefined
4098
6005
  });
4099
- const resolvedEnvironment = resolveConversationEnvironment(environment);
6006
+ const resolvedEnvironment = resolveConversationEnvironment(env);
4100
6007
  const now = resolvedEnvironment.now();
4101
- const next = {
6008
+ const next2 = {
4102
6009
  ...conversation,
4103
6010
  ids: [...conversation.ids],
4104
6011
  messages: { ...conversation.messages, [redacted.id]: redacted },
4105
6012
  updatedAt: now
4106
6013
  };
4107
- return toReadonly(next);
6014
+ return ensureConversationSafe(toReadonly(next2));
4108
6015
  }
4109
- function migrateConversation(json) {
4110
- if (typeof json !== "object" || json === null || Array.isArray(json)) {
4111
- return {
4112
- schemaVersion: CURRENT_SCHEMA_VERSION,
4113
- id: "",
4114
- status: "active",
4115
- metadata: {},
4116
- ids: [],
4117
- messages: {},
4118
- createdAt: new Date().toISOString(),
4119
- updatedAt: new Date().toISOString()
4120
- };
4121
- }
4122
- const data = json;
4123
- const rawMessages = data.messages;
4124
- let messages = {};
4125
- let ids = [];
4126
- const rawIds = data.ids;
4127
- const isStringArray = (value) => Array.isArray(value) && value.every((item) => typeof item === "string");
4128
- if (Array.isArray(rawMessages)) {
4129
- const rawMessageArray = rawMessages;
4130
- ids = rawMessageArray.map((message) => message.id);
4131
- messages = Object.fromEntries(rawMessageArray.map((message) => [message.id, message]));
4132
- } else if (rawMessages && typeof rawMessages === "object") {
4133
- messages = { ...rawMessages };
4134
- if (isStringArray(rawIds) && rawIds.length > 0) {
4135
- ids = [...rawIds];
4136
- } else {
4137
- ids = Object.values(messages).sort((a, b) => a.position - b.position).map((message) => message.id);
4138
- }
4139
- }
4140
- if (ids.length > 0) {
4141
- ids = ids.filter((id) => (id in messages));
4142
- const missing = Object.keys(messages).filter((id) => !ids.includes(id));
4143
- if (missing.length > 0) {
4144
- const sortedMissing = missing.sort((a, b) => (messages[a]?.position ?? 0) - (messages[b]?.position ?? 0));
4145
- ids = [...ids, ...sortedMissing];
4146
- }
4147
- }
4148
- if (!("schemaVersion" in json)) {
6016
+ // src/conversation/serialization.ts
6017
+ function normalizeToolResult(toolResult) {
6018
+ if (!toolResult)
6019
+ return;
6020
+ return {
6021
+ callId: toolResult.callId,
6022
+ outcome: toolResult.outcome,
6023
+ content: toolResult.content
6024
+ };
6025
+ }
6026
+ function normalizeMessage(message) {
6027
+ const base = {
6028
+ id: message.id,
6029
+ role: message.role,
6030
+ content: message.content,
6031
+ position: message.position,
6032
+ createdAt: message.createdAt,
6033
+ metadata: message.metadata,
6034
+ hidden: message.hidden,
6035
+ toolCall: message.toolCall ? { ...message.toolCall } : undefined,
6036
+ toolResult: normalizeToolResult(message.toolResult),
6037
+ tokenUsage: message.tokenUsage ? { ...message.tokenUsage } : undefined
6038
+ };
6039
+ if (isAssistantMessage(message)) {
4149
6040
  return {
4150
- ...data,
4151
- schemaVersion: CURRENT_SCHEMA_VERSION,
4152
- ids,
4153
- messages
6041
+ ...base,
6042
+ role: "assistant",
6043
+ goalCompleted: message.goalCompleted
4154
6044
  };
4155
6045
  }
4156
- return { ...data, ids, messages };
6046
+ return base;
4157
6047
  }
4158
6048
  function deserializeConversation(json) {
4159
- const migrated = migrateConversation(json);
6049
+ const parsed = conversationSchema.safeParse(json);
6050
+ if (!parsed.success) {
6051
+ throw createSerializationError("failed to deserialize conversation: invalid data");
6052
+ }
6053
+ const data = parsed.data;
4160
6054
  try {
4161
- const orderedMessages = migrated.ids.map((id, index) => {
4162
- const message = migrated.messages[id];
6055
+ const messageIds = new Set(Object.keys(data.messages));
6056
+ const orderedMessages = data.ids.map((id, index) => {
6057
+ const message = data.messages[id];
4163
6058
  if (!message) {
4164
6059
  throw createSerializationError(`missing message for id ${id}`);
4165
6060
  }
4166
6061
  if (message.position !== index) {
4167
6062
  throw createInvalidPositionError(index, message.position);
4168
6063
  }
4169
- return message;
6064
+ messageIds.delete(id);
6065
+ return normalizeMessage(message);
4170
6066
  });
6067
+ if (messageIds.size > 0) {
6068
+ throw createSerializationError(`messages not listed in ids: ${[...messageIds].join(", ")}`);
6069
+ }
4171
6070
  orderedMessages.reduce((state, message) => {
4172
6071
  if (message.role === "tool-use" && message.toolCall) {
4173
6072
  return {
@@ -4179,24 +6078,28 @@ function deserializeConversation(json) {
4179
6078
  }
4180
6079
  return state;
4181
6080
  }, { toolUses: new Map });
4182
- const messageInstances = orderedMessages.map((m) => createMessage(m));
6081
+ const messageInstances = orderedMessages.map((message) => createMessage(message));
4183
6082
  const conv = {
4184
- schemaVersion: migrated.schemaVersion,
4185
- id: migrated.id,
4186
- title: migrated.title,
4187
- status: migrated.status,
4188
- metadata: { ...migrated.metadata },
6083
+ schemaVersion: data.schemaVersion,
6084
+ id: data.id,
6085
+ title: data.title,
6086
+ status: data.status,
6087
+ metadata: { ...data.metadata },
4189
6088
  ids: orderedMessages.map((message) => message.id),
4190
6089
  messages: toIdRecord(messageInstances),
4191
- createdAt: migrated.createdAt,
4192
- updatedAt: migrated.updatedAt
6090
+ createdAt: data.createdAt,
6091
+ updatedAt: data.updatedAt
4193
6092
  };
4194
- return toReadonly(conv);
4195
- } catch (error) {
4196
- throw createSerializationError(`failed to deserialize conversation: ${error instanceof Error ? error.message : String(error)}`, error);
6093
+ const readonly = toReadonly(conv);
6094
+ assertConversationIntegrity(readonly);
6095
+ return readonly;
6096
+ } catch (error2) {
6097
+ throw createSerializationError(`failed to deserialize conversation: ${error2 instanceof Error ? error2.message : String(error2)}`, error2);
4197
6098
  }
4198
6099
  }
6100
+ // src/conversation/transform.ts
4199
6101
  function toChatMessages(conversation) {
6102
+ assertConversationSafe(conversation);
4200
6103
  const roleMap = {
4201
6104
  user: "user",
4202
6105
  assistant: "assistant",
@@ -4218,7 +6121,6 @@ function toChatMessages(conversation) {
4218
6121
  }
4219
6122
  return result;
4220
6123
  }
4221
-
4222
6124
  // src/streaming.ts
4223
6125
  var STREAMING_KEY = "__streaming";
4224
6126
  var cloneMessage = (original, overrides = {}) => {
@@ -4251,7 +6153,8 @@ function getStreamingMessage(conversation) {
4251
6153
  return getOrderedMessages(conversation).find(isStreamingMessage);
4252
6154
  }
4253
6155
  function appendStreamingMessage(conversation, role, metadata, environment) {
4254
- const resolvedEnvironment = resolveConversationEnvironment(environment);
6156
+ const resolvedEnvironment = resolveConversationEnvironment(isConversationEnvironmentParameter(metadata) ? metadata : environment);
6157
+ const resolvedMetadata = isConversationEnvironmentParameter(metadata) ? undefined : metadata;
4255
6158
  const now = resolvedEnvironment.now();
4256
6159
  const messageId = resolvedEnvironment.randomId();
4257
6160
  const newMessage = createMessage({
@@ -4260,7 +6163,7 @@ function appendStreamingMessage(conversation, role, metadata, environment) {
4260
6163
  content: "",
4261
6164
  position: conversation.ids.length,
4262
6165
  createdAt: now,
4263
- metadata: { ...metadata ?? {}, [STREAMING_KEY]: true },
6166
+ metadata: { ...resolvedMetadata ?? {}, [STREAMING_KEY]: true },
4264
6167
  hidden: false,
4265
6168
  toolCall: undefined,
4266
6169
  toolResult: undefined,
@@ -4272,14 +6175,14 @@ function appendStreamingMessage(conversation, role, metadata, environment) {
4272
6175
  messages: { ...conversation.messages, [messageId]: newMessage },
4273
6176
  updatedAt: now
4274
6177
  });
4275
- return { conversation: updatedConversation, messageId };
6178
+ return { conversation: ensureConversationSafe(updatedConversation), messageId };
4276
6179
  }
4277
6180
  function updateStreamingMessage(conversation, messageId, content, environment) {
4278
6181
  const resolvedEnvironment = resolveConversationEnvironment(environment);
4279
6182
  const now = resolvedEnvironment.now();
4280
6183
  const original = conversation.messages[messageId];
4281
6184
  if (!original) {
4282
- return conversation;
6185
+ return ensureConversationSafe(conversation);
4283
6186
  }
4284
6187
  const overrides = {
4285
6188
  content: typeof content === "string" ? content : [...content]
@@ -4288,44 +6191,45 @@ function updateStreamingMessage(conversation, messageId, content, environment) {
4288
6191
  overrides.tokenUsage = { ...original.tokenUsage };
4289
6192
  }
4290
6193
  const updated = cloneMessage(original, overrides);
4291
- return toReadonly({
6194
+ return ensureConversationSafe(toReadonly({
4292
6195
  ...conversation,
4293
6196
  ids: [...conversation.ids],
4294
6197
  messages: { ...conversation.messages, [updated.id]: updated },
4295
6198
  updatedAt: now
4296
- });
6199
+ }));
4297
6200
  }
4298
6201
  function finalizeStreamingMessage(conversation, messageId, options2, environment) {
4299
- const resolvedEnvironment = resolveConversationEnvironment(environment);
6202
+ const resolvedEnvironment = resolveConversationEnvironment(isConversationEnvironmentParameter(options2) ? options2 : environment);
6203
+ const resolvedOptions = isConversationEnvironmentParameter(options2) ? undefined : options2;
4300
6204
  const now = resolvedEnvironment.now();
4301
6205
  const original = conversation.messages[messageId];
4302
6206
  if (!original) {
4303
- return conversation;
6207
+ return ensureConversationSafe(conversation);
4304
6208
  }
4305
6209
  const { [STREAMING_KEY]: _, ...restMetadata } = original.metadata;
4306
6210
  const finalMetadata = {
4307
6211
  ...restMetadata,
4308
- ...options2?.metadata ?? {}
6212
+ ...resolvedOptions?.metadata ?? {}
4309
6213
  };
4310
6214
  const finalizeOverrides = {
4311
6215
  metadata: finalMetadata
4312
6216
  };
4313
- if (options2?.tokenUsage) {
4314
- finalizeOverrides.tokenUsage = { ...options2.tokenUsage };
6217
+ if (resolvedOptions?.tokenUsage) {
6218
+ finalizeOverrides.tokenUsage = { ...resolvedOptions.tokenUsage };
4315
6219
  }
4316
6220
  const updated = cloneMessage(original, finalizeOverrides);
4317
- return toReadonly({
6221
+ return ensureConversationSafe(toReadonly({
4318
6222
  ...conversation,
4319
6223
  ids: [...conversation.ids],
4320
6224
  messages: { ...conversation.messages, [updated.id]: updated },
4321
6225
  updatedAt: now
4322
- });
6226
+ }));
4323
6227
  }
4324
6228
  function cancelStreamingMessage(conversation, messageId, environment) {
4325
6229
  const resolvedEnvironment = resolveConversationEnvironment(environment);
4326
6230
  const now = resolvedEnvironment.now();
4327
6231
  if (!conversation.messages[messageId]) {
4328
- return conversation;
6232
+ return ensureConversationSafe(conversation);
4329
6233
  }
4330
6234
  const messages = getOrderedMessages(conversation).filter((m) => m.id !== messageId).map((message, index) => message.position === index ? message : (() => {
4331
6235
  const overrides = {
@@ -4336,29 +6240,26 @@ function cancelStreamingMessage(conversation, messageId, environment) {
4336
6240
  }
4337
6241
  return cloneMessage(message, overrides);
4338
6242
  })());
4339
- return toReadonly({
6243
+ return ensureConversationSafe(toReadonly({
4340
6244
  ...conversation,
4341
6245
  ids: messages.map((message) => message.id),
4342
6246
  messages: toIdRecord(messages),
4343
6247
  updatedAt: now
4344
- });
6248
+ }));
4345
6249
  }
4346
6250
 
4347
6251
  // src/history.ts
4348
- class ConversationHistoryEvent extends CustomEvent {
4349
- constructor(type, detail) {
4350
- super(type, { detail });
4351
- }
4352
- }
4353
-
4354
6252
  class ConversationHistory extends EventTarget {
4355
6253
  currentNode;
4356
6254
  environment;
6255
+ events;
4357
6256
  constructor(initial = createConversation(), environment) {
4358
6257
  super();
4359
6258
  this.environment = resolveConversationEnvironment(environment);
6259
+ this.events = createEventTarget();
6260
+ const safeInitial = ensureConversationSafe(initial);
4360
6261
  this.currentNode = {
4361
- conversation: initial,
6262
+ conversation: safeInitial,
4362
6263
  parent: null,
4363
6264
  children: []
4364
6265
  };
@@ -4368,25 +6269,54 @@ class ConversationHistory extends EventTarget {
4368
6269
  type,
4369
6270
  conversation: this.current
4370
6271
  };
4371
- this.dispatchEvent(new ConversationHistoryEvent("change", detail));
4372
- this.dispatchEvent(new ConversationHistoryEvent(type, detail));
6272
+ this.events.dispatchEvent({ type: "change", detail });
6273
+ this.events.dispatchEvent({ type, detail });
6274
+ }
6275
+ toAddListenerOptions(options2) {
6276
+ if (typeof options2 === "boolean" || options2 === undefined)
6277
+ return options2;
6278
+ const mapped = {};
6279
+ if (options2.capture !== undefined)
6280
+ mapped.capture = options2.capture;
6281
+ if (options2.once !== undefined)
6282
+ mapped.once = options2.once;
6283
+ if (options2.passive !== undefined)
6284
+ mapped.passive = options2.passive;
6285
+ if (options2.signal !== undefined) {
6286
+ mapped.signal = options2.signal;
6287
+ }
6288
+ return mapped;
6289
+ }
6290
+ toRemoveListenerOptions(options2) {
6291
+ if (typeof options2 === "boolean" || options2 === undefined)
6292
+ return options2;
6293
+ const mapped = {};
6294
+ if (options2.capture !== undefined)
6295
+ mapped.capture = options2.capture;
6296
+ return mapped;
4373
6297
  }
4374
6298
  addEventListener(type, callback, options2) {
4375
6299
  if (!callback)
4376
6300
  return;
4377
- super.addEventListener(type, callback, options2);
4378
- const unsubscribe = () => this.removeEventListener(type, callback, options2);
4379
- return unsubscribe;
6301
+ return this.events.addEventListener(type, callback, this.toAddListenerOptions(options2));
6302
+ }
6303
+ removeEventListener(type, callback, options2) {
6304
+ if (!callback)
6305
+ return;
6306
+ this.events.removeEventListener(type, callback, this.toRemoveListenerOptions(options2));
6307
+ }
6308
+ dispatchEvent(event) {
6309
+ return this.events.dispatchEvent(event);
4380
6310
  }
4381
6311
  subscribe(run) {
4382
6312
  run(this.current);
4383
6313
  const handler = (event) => {
4384
- if (event instanceof ConversationHistoryEvent) {
6314
+ if (event?.detail?.conversation) {
4385
6315
  run(event.detail.conversation);
4386
6316
  }
4387
6317
  };
4388
- const unsubscribe = this.addEventListener("change", handler);
4389
- return unsubscribe || (() => {});
6318
+ const unsubscribe2 = this.addEventListener("change", handler);
6319
+ return unsubscribe2 || (() => {});
4390
6320
  }
4391
6321
  getSnapshot() {
4392
6322
  return this.current;
@@ -4417,9 +6347,9 @@ class ConversationHistory extends EventTarget {
4417
6347
  get redoCount() {
4418
6348
  return this.currentNode.children.length;
4419
6349
  }
4420
- push(next) {
6350
+ push(next2) {
4421
6351
  const newNode = {
4422
- conversation: next,
6352
+ conversation: next2,
4423
6353
  parent: this.currentNode,
4424
6354
  children: []
4425
6355
  };
@@ -4436,9 +6366,9 @@ class ConversationHistory extends EventTarget {
4436
6366
  return;
4437
6367
  }
4438
6368
  redo(childIndex = 0) {
4439
- const next = this.currentNode.children[childIndex];
4440
- if (next) {
4441
- this.currentNode = next;
6369
+ const next2 = this.currentNode.children[childIndex];
6370
+ if (next2) {
6371
+ this.currentNode = next2;
4442
6372
  this.notifyChange("redo");
4443
6373
  return this.current;
4444
6374
  }
@@ -4527,8 +6457,8 @@ class ConversationHistory extends EventTarget {
4527
6457
  collapseSystemMessages() {
4528
6458
  this.push(collapseSystemMessages(this.current, this.env));
4529
6459
  }
4530
- redactMessageAtPosition(position, placeholder) {
4531
- this.push(redactMessageAtPosition(this.current, position, placeholder, this.env));
6460
+ redactMessageAtPosition(position, placeholderOrOptions) {
6461
+ this.push(redactMessageAtPosition(this.current, position, placeholderOrOptions, this.env));
4532
6462
  }
4533
6463
  truncateFromPosition(position, options2) {
4534
6464
  this.push(truncateFromPosition(this.current, position, options2, this.env));
@@ -4625,6 +6555,7 @@ class ConversationHistory extends EventTarget {
4625
6555
  };
4626
6556
  if (root)
4627
6557
  clearNode(root);
6558
+ this.events.clear();
4628
6559
  }
4629
6560
  }
4630
6561
  function isConversation(value) {
@@ -4633,23 +6564,6 @@ function isConversation(value) {
4633
6564
 
4634
6565
  // src/utilities/markdown.ts
4635
6566
  var import_gray_matter = __toESM(require_gray_matter(), 1);
4636
-
4637
- // src/utilities/tool-results.ts
4638
- function copyToolResult(toolResult) {
4639
- return { ...toolResult };
4640
- }
4641
- function redactToolResult(toolResult, placeholder) {
4642
- const result = { ...toolResult, content: placeholder };
4643
- if (result.result !== undefined) {
4644
- result.result = placeholder;
4645
- }
4646
- if (result.error !== undefined) {
4647
- result.error = placeholder;
4648
- }
4649
- return result;
4650
- }
4651
-
4652
- // src/utilities/markdown.ts
4653
6567
  var ROLE_LABELS = {
4654
6568
  user: "User",
4655
6569
  assistant: "Assistant",
@@ -4659,7 +6573,6 @@ var ROLE_LABELS = {
4659
6573
  "tool-result": "Tool Result",
4660
6574
  snapshot: "Snapshot"
4661
6575
  };
4662
- var ROLE_DISPLAY_NAMES = ROLE_LABELS;
4663
6576
  var LABEL_TO_ROLE = {
4664
6577
  User: "user",
4665
6578
  Assistant: "assistant",
@@ -4669,7 +6582,6 @@ var LABEL_TO_ROLE = {
4669
6582
  "Tool Result": "tool-result",
4670
6583
  Snapshot: "snapshot"
4671
6584
  };
4672
- var DISPLAY_NAME_TO_ROLE = LABEL_TO_ROLE;
4673
6585
  function getRoleLabel(role) {
4674
6586
  return ROLE_LABELS[role];
4675
6587
  }
@@ -4752,6 +6664,7 @@ function formatMessageContent(message) {
4752
6664
  `);
4753
6665
  }
4754
6666
  function toMarkdown(conversation, options2 = {}) {
6667
+ assertConversationSafe(conversation);
4755
6668
  const resolved = resolveMarkdownOptions(options2);
4756
6669
  const prepared = prepareConversationForMarkdown(conversation, resolved);
4757
6670
  if (resolved.includeMetadata) {
@@ -4762,7 +6675,7 @@ function toMarkdown(conversation, options2 = {}) {
4762
6675
  function toMarkdownSimple(conversation) {
4763
6676
  const sections = [];
4764
6677
  for (const message of getOrderedMessages(conversation)) {
4765
- const roleName = ROLE_DISPLAY_NAMES[message.role];
6678
+ const roleName = ROLE_LABELS[message.role];
4766
6679
  const header = `### ${roleName}`;
4767
6680
  const content = formatMessageContent(message);
4768
6681
  sections.push(`${header}
@@ -4813,7 +6726,7 @@ function toMarkdownWithMetadata(conversation, _options) {
4813
6726
  }
4814
6727
  const messageSections = [];
4815
6728
  for (const message of getOrderedMessages(conversation)) {
4816
- const roleName = ROLE_DISPLAY_NAMES[message.role];
6729
+ const roleName = ROLE_LABELS[message.role];
4817
6730
  const header = `### ${roleName} (${message.id})`;
4818
6731
  const content = formatMessageContent(message);
4819
6732
  messageSections.push(`${header}
@@ -4838,10 +6751,13 @@ function generateId() {
4838
6751
  function fromMarkdown(markdown) {
4839
6752
  const trimmed = markdown.trim();
4840
6753
  const hasFrontmatter = trimmed.startsWith("---");
4841
- if (hasFrontmatter) {
4842
- return parseMarkdownWithMetadata(trimmed);
6754
+ const conversation = hasFrontmatter ? parseMarkdownWithMetadata(trimmed) : parseMarkdownSimple(trimmed);
6755
+ try {
6756
+ assertConversationSafe(conversation);
6757
+ } catch (error2) {
6758
+ throw new MarkdownParseError(`Invalid markdown conversation: ${error2 instanceof Error ? error2.message : String(error2)}`);
4843
6759
  }
4844
- return parseMarkdownSimple(trimmed);
6760
+ return conversation;
4845
6761
  }
4846
6762
  function parseMarkdownWithMetadata(trimmed) {
4847
6763
  let parsed;
@@ -4860,7 +6776,7 @@ function parseMarkdownWithMetadata(trimmed) {
4860
6776
  let match;
4861
6777
  while ((match = messagePattern.exec(body)) !== null) {
4862
6778
  const [, roleDisplay, messageId, contentBody] = match;
4863
- const role = DISPLAY_NAME_TO_ROLE[roleDisplay];
6779
+ const role = LABEL_TO_ROLE[roleDisplay];
4864
6780
  if (!role) {
4865
6781
  throw new MarkdownParseError(`Unknown role: ${roleDisplay}`);
4866
6782
  }
@@ -4917,7 +6833,7 @@ function parseMarkdownSimple(body) {
4917
6833
  let position = 0;
4918
6834
  while ((match = messagePattern.exec(body)) !== null) {
4919
6835
  const [, roleDisplay, contentBody] = match;
4920
- const role = DISPLAY_NAME_TO_ROLE[roleDisplay];
6836
+ const role = LABEL_TO_ROLE[roleDisplay];
4921
6837
  if (!role) {
4922
6838
  throw new MarkdownParseError(`Unknown role: ${roleDisplay}`);
4923
6839
  }
@@ -4966,4 +6882,4 @@ export {
4966
6882
  LABEL_TO_ROLE
4967
6883
  };
4968
6884
 
4969
- //# debugId=958A518551DE0FA964756E2164756E21
6885
+ //# debugId=C9F3624DCBE2A76564756E2164756E21