@elizaos/plugin-knowledge 1.0.0-beta.78 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}:root{--background: 0 0% 97.65%;--foreground: 0 0% 12.55%;--muted: 0 0% 93.73%;--muted-foreground: 0 0% 39.22%;--popover: 0 0% 98.82%;--popover-foreground: 0 0% 12.55%;--card: 0 0% 98.82%;--card-foreground: 0 0% 12.55%;--border: 0 0% 84.71%;--input: 0 0% 94.12%;--primary: 22.93 92.59% 52.35%;--primary-foreground: 44 0% 100%;--secondary: 34.05 100% 85.49%;--secondary-foreground: 16.27 50.43% 22.94%;--accent: 0 0% 90.98%;--accent-foreground: 0 0% 12.55%;--destructive: 10.16 77.87% 53.92%;--destructive-foreground: 0 0% 100%;--ring: 24.8 79.79% 63.14%;--chart-1: 22.93 92.59% 52.35%;--chart-2: 34.05 100% 85.49%;--chart-3: 0 0% 90.98%;--chart-4: 34.05 100% 88.49%;--chart-5: 22.93 95.59% 52.35%;--radius: .5rem}*{border-color:hsl(var(--border))}body{background-color:hsl(var(--background));color:hsl(var(--foreground))}.container{width:100%;margin-right:auto;margin-left:auto}@media (min-width: 640px){.container{max-width:640px}}@media (min-width: 768px){.container{max-width:768px}}@media (min-width: 1024px){.container{max-width:1024px}}@media (min-width: 1280px){.container{max-width:1280px}}@media (min-width: 1536px){.container{max-width:1536px}}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.left-3{left:.75rem}.left-4{left:1rem}.right-4{right:1rem}.top-16{top:4rem}.top-3{top:.75rem}.top-4{top:1rem}.z-50{z-index:50}.col-span-2{grid-column:span 2 / span 2}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.mr-1\.5{margin-right:.375rem}.mr-2{margin-right:.5rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.size-6{width:1.5rem;height:1.5rem}.h-1\/3{height:33.333333%}.h-10{height:2.5rem}.h-11{height:2.75rem}.h-12{height:3rem}.h-2\/3{height:66.666667%}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-40{height:10rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-9{height:2.25rem}.h-full{height:100%}.max-h-40{max-height:10rem}.max-h-\[95vh\]{max-height:95vh}.max-h-full{max-height:100%}.w-10{width:2.5rem}.w-12{width:3rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-6{width:1.5rem}.w-full{width:100%}.min-w-\[60px\]{min-width:60px}.min-w-full{min-width:100%}.max-w-\[95vw\]{max-width:95vw}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.resize{resize:both}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.items-start{align-items:flex-start}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-x-4{-moz-column-gap:1rem;column-gap:1rem}.gap-y-1{row-gap:.25rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.border{border-width:1px}.border-0{border-width:0px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-border{border-color:hsl(var(--border))}.border-gray-500\/60{border-color:#6b728099}.border-input{border-color:hsl(var(--input))}.border-orange-600\/60{border-color:#ea580c99}.bg-accent{background-color:hsl(var(--accent))}.bg-accent\/20{background-color:hsl(var(--accent) / .2)}.bg-background{background-color:hsl(var(--background))}.bg-background\/80{background-color:hsl(var(--background) / .8)}.bg-card{background-color:hsl(var(--card))}.bg-card\/50{background-color:hsl(var(--card) / .5)}.bg-card\/90{background-color:hsl(var(--card) / .9)}.bg-destructive{background-color:hsl(var(--destructive))}.bg-destructive\/10{background-color:hsl(var(--destructive) / .1)}.bg-gray-400\/90{background-color:#9ca3afe6}.bg-muted{background-color:hsl(var(--muted))}.bg-muted\/30{background-color:hsl(var(--muted) / .3)}.bg-muted\/50{background-color:hsl(var(--muted) / .5)}.bg-orange-500\/90{background-color:#f97316e6}.bg-primary{background-color:hsl(var(--primary))}.bg-secondary{background-color:hsl(var(--secondary))}.p-0{padding:0}.p-1{padding:.25rem}.p-12{padding:3rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0{padding-top:0;padding-bottom:0}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.pb-2{padding-bottom:.5rem}.pb-4{padding-bottom:1rem}.pl-10{padding-left:2.5rem}.pt-0{padding-top:0}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.tracking-tight{letter-spacing:-.025em}.text-accent-foreground{color:hsl(var(--accent-foreground))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-card-foreground{color:hsl(var(--card-foreground))}.text-destructive{color:hsl(var(--destructive))}.text-destructive-foreground{color:hsl(var(--destructive-foreground))}.text-foreground{color:hsl(var(--foreground))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-muted-foreground{color:hsl(var(--muted-foreground))}.text-primary-foreground{color:hsl(var(--primary-foreground))}.text-primary\/80{color:hsl(var(--primary) / .8)}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-secondary-foreground{color:hsl(var(--secondary-foreground))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-70{opacity:.7}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline{outline-style:solid}.ring-offset-background{--tw-ring-offset-color: hsl(var(--background))}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-300{transition-duration:.3s}@keyframes enter{0%{opacity:var(--tw-enter-opacity, 1);transform:translate3d(var(--tw-enter-translate-x, 0),var(--tw-enter-translate-y, 0),0) scale3d(var(--tw-enter-scale, 1),var(--tw-enter-scale, 1),var(--tw-enter-scale, 1)) rotate(var(--tw-enter-rotate, 0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity, 1);transform:translate3d(var(--tw-exit-translate-x, 0),var(--tw-exit-translate-y, 0),0) scale3d(var(--tw-exit-scale, 1),var(--tw-exit-scale, 1),var(--tw-exit-scale, 1)) rotate(var(--tw-exit-rotate, 0))}}.duration-300{animation-duration:.3s}*{--background: 0 0% 6.67%;--foreground: 0 0% 93.33%;--muted: 0 0% 13.33%;--muted-foreground: 0 0% 70.59%;--popover: 0 0% 9.8%;--popover-foreground: 0 0% 93.33%;--card: 0 0% 9.8%;--card-foreground: 0 0% 93.33%;--border: 44 14% 11%;--input: 0 0% 28.24%;--primary: 22.93 92.59% 52.35%;--primary-foreground: 29.51 0% 100%;--secondary: 28.5 64.52% 12.16%;--secondary-foreground: 29.51 100% 88.04%;--accent: 0 0% 16.47%;--accent-foreground: 0 0% 93.33%;--destructive: 10.16 77.87% 53.92%;--destructive-foreground: 0 0% 100%;--ring: 23.11 59.8% 40%;--chart-1: 22.93 92.59% 52.35%;--chart-2: 28.5 64.52% 12.16%;--chart-3: 0 0% 16.47%;--chart-4: 28.5 64.52% 15.16%;--chart-5: 22.93 95.59% 52.35%;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.file\:border-0::file-selector-button{border-width:0px}.file\:bg-transparent::file-selector-button{background-color:transparent}.file\:text-sm::file-selector-button{font-size:.875rem;line-height:1.25rem}.file\:font-medium::file-selector-button{font-weight:500}.placeholder\:text-muted-foreground::-moz-placeholder{color:hsl(var(--muted-foreground))}.placeholder\:text-muted-foreground::placeholder{color:hsl(var(--muted-foreground))}.hover\:bg-accent:hover{background-color:hsl(var(--accent))}.hover\:bg-accent\/10:hover{background-color:hsl(var(--accent) / .1)}.hover\:bg-destructive\/10:hover{background-color:hsl(var(--destructive) / .1)}.hover\:bg-destructive\/90:hover{background-color:hsl(var(--destructive) / .9)}.hover\:bg-muted\/50:hover{background-color:hsl(var(--muted) / .5)}.hover\:bg-primary\/90:hover{background-color:hsl(var(--primary) / .9)}.hover\:text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:text-destructive:hover{color:hsl(var(--destructive))}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color: hsl(var(--ring))}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width: 2px}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:opacity-100{opacity:1}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:hsl(var(--background))}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:hsl(var(--muted))}.data-\[state\=active\]\:text-foreground[data-state=active]{color:hsl(var(--foreground))}.data-\[state\=active\]\:shadow[data-state=active]{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:0}.\[\&\>\[role\=checkbox\]\]\:translate-y-\[2px\]>[role=checkbox]{--tw-translate-y: 2px;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.\[\&\>tr\]\:last\:border-b-0:last-child>tr{border-bottom-width:0px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-width:0px}.\[\&_tr\]\:border-b tr{border-bottom-width:1px}
@@ -262,6 +262,15 @@ function isBinaryContentType(contentType, filename) {
262
262
  function isTextItem(item) {
263
263
  return "str" in item;
264
264
  }
265
+ function normalizeS3Url(url) {
266
+ try {
267
+ const urlObj = new URL(url);
268
+ return `${urlObj.origin}${urlObj.pathname}`;
269
+ } catch (error) {
270
+ logger.warn(`[URL NORMALIZER] Failed to parse URL: ${url}. Returning original.`);
271
+ return url;
272
+ }
273
+ }
265
274
  async function fetchUrlContent(url) {
266
275
  logger.debug(`[URL FETCHER] Fetching content from URL: ${url}`);
267
276
  try {
@@ -500,8 +509,9 @@ export {
500
509
  extractTextFromFileBuffer,
501
510
  convertPdfToTextFromBuffer,
502
511
  isBinaryContentType,
512
+ normalizeS3Url,
503
513
  fetchUrlContent,
504
514
  getKnowledgePath,
505
515
  loadDocsFromPath
506
516
  };
507
- //# sourceMappingURL=chunk-HUTF5APY.js.map
517
+ //# sourceMappingURL=chunk-BB6B27BS.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/docs-loader.ts","../src/utils.ts"],"sourcesContent":["import { logger, UUID, createUniqueUuid } from \"@elizaos/core\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { KnowledgeService } from \"./service.ts\";\nimport { AddKnowledgeOptions } from \"./types.ts\";\nimport { isBinaryContentType } from './utils.ts';\n\n/**\n * Get the knowledge path from environment or default to ./docs\n */\nexport function getKnowledgePath(): string {\n const envPath = process.env.KNOWLEDGE_PATH;\n\n if (envPath) {\n // Resolve relative paths from current working directory\n const resolvedPath = path.resolve(envPath);\n\n if (!fs.existsSync(resolvedPath)) {\n logger.warn(`Knowledge path from environment variable does not exist: ${resolvedPath}`);\n logger.warn('Please create the directory or update KNOWLEDGE_PATH environment variable');\n }\n\n return resolvedPath;\n }\n\n // Default to docs folder in current working directory\n const defaultPath = path.join(process.cwd(), 'docs');\n\n if (!fs.existsSync(defaultPath)) {\n logger.info(`Default docs folder does not exist at: ${defaultPath}`);\n logger.info('To use the knowledge plugin, either:');\n logger.info('1. Create a \"docs\" folder in your project root');\n logger.info('2. Set KNOWLEDGE_PATH environment variable to your documents folder');\n }\n\n return defaultPath;\n}\n\n/**\n * Load documents from the knowledge path\n */\nexport async function loadDocsFromPath(\n service: KnowledgeService,\n agentId: UUID,\n worldId?: UUID\n): Promise<{ total: number; successful: number; failed: number }> {\n const docsPath = getKnowledgePath();\n\n if (!fs.existsSync(docsPath)) {\n logger.warn(`Knowledge path does not exist: ${docsPath}`);\n return { total: 0, successful: 0, failed: 0 };\n }\n\n logger.info(`Loading documents from: ${docsPath}`);\n\n // Get all files recursively\n const files = getAllFiles(docsPath);\n\n if (files.length === 0) {\n logger.info('No files found in knowledge path');\n return { total: 0, successful: 0, failed: 0 };\n }\n\n logger.info(`Found ${files.length} files to process`);\n\n let successful = 0;\n let failed = 0;\n\n for (const filePath of files) {\n try {\n const fileName = path.basename(filePath);\n const fileExt = path.extname(filePath).toLowerCase();\n\n // Skip hidden files and directories\n if (fileName.startsWith('.')) {\n continue;\n }\n\n // Determine content type\n const contentType = getContentType(fileExt);\n\n // Skip unsupported file types\n if (!contentType) {\n logger.debug(`Skipping unsupported file type: ${filePath}`);\n continue;\n }\n\n // Read file\n const fileBuffer = fs.readFileSync(filePath);\n\n // Check if file is binary using the same logic as the service\n const isBinary = isBinaryContentType(contentType, fileName);\n\n // For text files, read as UTF-8 string directly\n // For binary files, convert to base64\n const content = isBinary ? fileBuffer.toString('base64') : fileBuffer.toString('utf-8');\n\n // Create knowledge options\n const knowledgeOptions: AddKnowledgeOptions = {\n clientDocumentId: createUniqueUuid(agentId, `docs-${fileName}-${Date.now()}`) as UUID,\n contentType,\n originalFilename: fileName,\n worldId: worldId || agentId,\n content,\n roomId: agentId,\n entityId: agentId,\n };\n\n // Process the document\n logger.debug(`Processing document: ${fileName}`);\n const result = await service.addKnowledge(knowledgeOptions);\n\n logger.info(`Successfully processed ${fileName}: ${result.fragmentCount} fragments created`);\n successful++;\n } catch (error) {\n logger.error(`Failed to process file ${filePath}:`, error);\n failed++;\n }\n }\n\n logger.info(\n `Document loading complete: ${successful} successful, ${failed} failed out of ${files.length} total`\n );\n\n return {\n total: files.length,\n successful,\n failed,\n };\n}\n\n/**\n * Recursively get all files in a directory\n */\nfunction getAllFiles(dirPath: string, files: string[] = []): string[] {\n try {\n const entries = fs.readdirSync(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dirPath, entry.name);\n\n if (entry.isDirectory()) {\n // Skip node_modules and other common directories\n if (!['node_modules', '.git', '.vscode', 'dist', 'build'].includes(entry.name)) {\n getAllFiles(fullPath, files);\n }\n } else if (entry.isFile()) {\n files.push(fullPath);\n }\n }\n } catch (error) {\n logger.error(`Error reading directory ${dirPath}:`, error);\n }\n\n return files;\n}\n\n/**\n * Get content type based on file extension\n */\nfunction getContentType(extension: string): string | null {\n const contentTypes: Record<string, string> = {\n // Text documents\n '.txt': 'text/plain',\n '.md': 'text/markdown',\n '.markdown': 'text/markdown',\n '.tson': 'text/plain',\n '.xml': 'application/xml',\n '.csv': 'text/csv',\n '.tsv': 'text/tab-separated-values',\n '.log': 'text/plain',\n\n // Web files\n '.html': 'text/html',\n '.htm': 'text/html',\n '.css': 'text/css',\n '.scss': 'text/x-scss',\n '.sass': 'text/x-sass',\n '.less': 'text/x-less',\n\n // JavaScript/TypeScript\n '.js': 'text/javascript',\n '.jsx': 'text/javascript',\n '.ts': 'text/typescript',\n '.tsx': 'text/typescript',\n '.mjs': 'text/javascript',\n '.cjs': 'text/javascript',\n '.vue': 'text/x-vue',\n '.svelte': 'text/x-svelte',\n '.astro': 'text/x-astro',\n\n // Python\n '.py': 'text/x-python',\n '.pyw': 'text/x-python',\n '.pyi': 'text/x-python',\n\n // Java/Kotlin/Scala\n '.java': 'text/x-java',\n '.kt': 'text/x-kotlin',\n '.kts': 'text/x-kotlin',\n '.scala': 'text/x-scala',\n\n // C/C++/C#\n '.c': 'text/x-c',\n '.cpp': 'text/x-c++',\n '.cc': 'text/x-c++',\n '.cxx': 'text/x-c++',\n '.h': 'text/x-c',\n '.hpp': 'text/x-c++',\n '.cs': 'text/x-csharp',\n\n // Other languages\n '.php': 'text/x-php',\n '.rb': 'text/x-ruby',\n '.go': 'text/x-go',\n '.rs': 'text/x-rust',\n '.swift': 'text/x-swift',\n '.r': 'text/x-r',\n '.R': 'text/x-r',\n '.m': 'text/x-objectivec',\n '.mm': 'text/x-objectivec',\n '.clj': 'text/x-clojure',\n '.cljs': 'text/x-clojure',\n '.ex': 'text/x-elixir',\n '.exs': 'text/x-elixir',\n '.lua': 'text/x-lua',\n '.pl': 'text/x-perl',\n '.pm': 'text/x-perl',\n '.dart': 'text/x-dart',\n '.hs': 'text/x-haskell',\n '.elm': 'text/x-elm',\n '.ml': 'text/x-ocaml',\n '.fs': 'text/x-fsharp',\n '.fsx': 'text/x-fsharp',\n '.vb': 'text/x-vb',\n '.pas': 'text/x-pascal',\n '.d': 'text/x-d',\n '.nim': 'text/x-nim',\n '.zig': 'text/x-zig',\n '.jl': 'text/x-julia',\n '.tcl': 'text/x-tcl',\n '.awk': 'text/x-awk',\n '.sed': 'text/x-sed',\n\n // Shell scripts\n '.sh': 'text/x-sh',\n '.bash': 'text/x-sh',\n '.zsh': 'text/x-sh',\n '.fish': 'text/x-fish',\n '.ps1': 'text/x-powershell',\n '.bat': 'text/x-batch',\n '.cmd': 'text/x-batch',\n\n // Config files\n '.json': 'application/json',\n '.yaml': 'text/x-yaml',\n '.yml': 'text/x-yaml',\n '.toml': 'text/x-toml',\n '.ini': 'text/x-ini',\n '.cfg': 'text/x-ini',\n '.conf': 'text/x-ini',\n '.env': 'text/plain',\n '.gitignore': 'text/plain',\n '.dockerignore': 'text/plain',\n '.editorconfig': 'text/plain',\n '.properties': 'text/x-properties',\n\n // Database\n '.sql': 'text/x-sql',\n\n // Binary documents\n '.pdf': 'application/pdf',\n '.doc': 'application/msword',\n '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n };\n\n return contentTypes[extension] || null;\n}\n","import { Buffer } from 'node:buffer';\nimport * as mammoth from 'mammoth';\nimport { logger } from '@elizaos/core';\nimport { getDocument, PDFDocumentProxy } from 'pdfjs-dist/legacy/build/pdf.mjs';\nimport type { TextItem, TextMarkedContent } from 'pdfjs-dist/types/src/display/api';\n\nconst PLAIN_TEXT_CONTENT_TYPES = [\n 'application/typescript',\n 'text/typescript',\n 'text/x-python',\n 'application/x-python-code',\n 'application/yaml',\n 'text/yaml',\n 'application/x-yaml',\n 'application/json',\n 'text/markdown',\n 'text/csv',\n];\n\nconst MAX_FALLBACK_SIZE_BYTES = 5 * 1024 * 1024; // 5 MB\nconst BINARY_CHECK_BYTES = 1024; // Check first 1KB for binary indicators\n\n/**\n * Extracts text content from a file buffer based on its content type.\n * Supports DOCX, plain text, and provides a fallback for unknown types.\n * PDF should be handled by `convertPdfToTextFromBuffer`.\n */\nexport async function extractTextFromFileBuffer(\n fileBuffer: Buffer,\n contentType: string,\n originalFilename: string // For logging and context\n): Promise<string> {\n const lowerContentType = contentType.toLowerCase();\n logger.debug(\n `[TextUtil] Attempting to extract text from ${originalFilename} (type: ${contentType})`\n );\n\n if (\n lowerContentType === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'\n ) {\n logger.debug(`[TextUtil] Extracting text from DOCX ${originalFilename} via mammoth.`);\n try {\n const result = await mammoth.extractRawText({ buffer: fileBuffer });\n logger.debug(\n `[TextUtil] DOCX text extraction complete for ${originalFilename}. Text length: ${result.value.length}`\n );\n return result.value;\n } catch (docxError: any) {\n const errorMsg = `[TextUtil] Failed to parse DOCX file ${originalFilename}: ${docxError.message}`;\n logger.error(errorMsg, docxError.stack);\n throw new Error(errorMsg);\n }\n } else if (\n lowerContentType === 'application/msword' ||\n originalFilename.toLowerCase().endsWith('.doc')\n ) {\n // For .doc files, we'll store the content as-is, and just add a message\n // The frontend will handle the display appropriately\n logger.debug(`[TextUtil] Handling Microsoft Word .doc file: ${originalFilename}`);\n\n // We'll add a descriptive message as a placeholder\n return `[Microsoft Word Document: ${originalFilename}]\\n\\nThis document was indexed for search but cannot be displayed directly in the browser. The original document content is preserved for retrieval purposes.`;\n } else if (\n lowerContentType.startsWith('text/') ||\n PLAIN_TEXT_CONTENT_TYPES.includes(lowerContentType)\n ) {\n logger.debug(\n `[TextUtil] Extracting text from plain text compatible file ${originalFilename} (type: ${contentType})`\n );\n return fileBuffer.toString('utf-8');\n } else {\n logger.warn(\n `[TextUtil] Unsupported content type: \"${contentType}\" for ${originalFilename}. Attempting fallback to plain text.`\n );\n\n if (fileBuffer.length > MAX_FALLBACK_SIZE_BYTES) {\n const sizeErrorMsg = `[TextUtil] File ${originalFilename} (type: ${contentType}) exceeds maximum size for fallback (${MAX_FALLBACK_SIZE_BYTES} bytes). Cannot process as plain text.`;\n logger.error(sizeErrorMsg);\n throw new Error(sizeErrorMsg);\n }\n\n // Simple binary detection: check for null bytes in the first N bytes\n const initialBytes = fileBuffer.subarray(0, Math.min(fileBuffer.length, BINARY_CHECK_BYTES));\n if (initialBytes.includes(0)) {\n // Check for NUL byte\n const binaryHeuristicMsg = `[TextUtil] File ${originalFilename} (type: ${contentType}) appears to be binary based on initial byte check. Cannot process as plain text.`;\n logger.error(binaryHeuristicMsg);\n throw new Error(binaryHeuristicMsg);\n }\n\n try {\n const textContent = fileBuffer.toString('utf-8');\n if (textContent.includes('\\ufffd')) {\n // Replacement character, indicating potential binary or wrong encoding\n const binaryErrorMsg = `[TextUtil] File ${originalFilename} (type: ${contentType}) seems to be binary or has encoding issues after fallback to plain text (detected \\ufffd).`;\n logger.error(binaryErrorMsg);\n throw new Error(binaryErrorMsg); // Throw error for likely binary content\n }\n logger.debug(\n `[TextUtil] Successfully processed unknown type ${contentType} as plain text after fallback for ${originalFilename}.`\n );\n return textContent;\n } catch (fallbackError: any) {\n // If the initial toString failed or if we threw due to \\ufffd\n const finalErrorMsg = `[TextUtil] Unsupported content type: ${contentType} for ${originalFilename}. Fallback to plain text also failed or indicated binary content.`;\n logger.error(finalErrorMsg, fallbackError.message ? fallbackError.stack : undefined);\n throw new Error(finalErrorMsg);\n }\n }\n}\n\n/**\n * Converts a PDF file buffer to text content.\n * Requires pdfjs-dist to be properly configured, especially its worker.\n */\n/**\n * Converts a PDF Buffer to text with enhanced formatting preservation.\n *\n * @param {Buffer} pdfBuffer - The PDF Buffer to convert to text\n * @param {string} [filename] - Optional filename for logging purposes\n * @returns {Promise<string>} Text content of the PDF\n */\nexport async function convertPdfToTextFromBuffer(\n pdfBuffer: Buffer,\n filename?: string\n): Promise<string> {\n const docName = filename || 'unnamed-document';\n logger.debug(`[PdfService] Starting conversion for ${docName}`);\n\n try {\n const uint8Array = new Uint8Array(pdfBuffer);\n const pdf: PDFDocumentProxy = await getDocument({ data: uint8Array }).promise;\n const numPages = pdf.numPages;\n const textPages: string[] = [];\n\n for (let pageNum = 1; pageNum <= numPages; pageNum++) {\n logger.debug(`[PdfService] Processing page ${pageNum}/${numPages}`);\n const page = await pdf.getPage(pageNum);\n const textContent = await page.getTextContent();\n\n // Group text items by their y-position to maintain line structure\n const lineMap = new Map<number, TextItem[]>();\n\n textContent.items.filter(isTextItem).forEach((item) => {\n // Round y-position to account for small variations in the same line\n const yPos = Math.round(item.transform[5]);\n if (!lineMap.has(yPos)) {\n lineMap.set(yPos, []);\n }\n lineMap.get(yPos)!.push(item);\n });\n\n // Sort lines by y-position (top to bottom) and items within lines by x-position (left to right)\n const sortedLines = Array.from(lineMap.entries())\n .sort((a, b) => b[0] - a[0]) // Reverse sort for top-to-bottom\n .map(([_, items]) =>\n items\n .sort((a, b) => a.transform[4] - b.transform[4])\n .map((item) => item.str)\n .join(' ')\n );\n\n textPages.push(sortedLines.join('\\n'));\n }\n\n const fullText = textPages.join('\\n\\n').replace(/\\s+/g, ' ').trim();\n logger.debug(`[PdfService] Conversion complete for ${docName}, length: ${fullText.length}`);\n return fullText;\n } catch (error: any) {\n logger.error(`[PdfService] Error converting PDF ${docName}:`, error.message);\n throw new Error(`Failed to convert PDF to text: ${error.message}`);\n }\n}\n\n/**\n * Determines if a file should be treated as binary based on its content type and filename\n * @param contentType MIME type of the file\n * @param filename Original filename\n * @returns True if the file should be treated as binary (base64 encoded)\n */\nexport function isBinaryContentType(contentType: string, filename: string): boolean {\n // Text-based content types that should NOT be treated as binary\n const textContentTypes = [\n 'text/',\n 'application/json',\n 'application/xml',\n 'application/javascript',\n 'application/typescript',\n 'application/x-yaml',\n 'application/x-sh',\n ];\n\n // Check if it's a text-based MIME type\n const isTextMimeType = textContentTypes.some((type) => contentType.includes(type));\n if (isTextMimeType) {\n return false;\n }\n\n // Binary content types\n const binaryContentTypes = [\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument',\n 'application/vnd.ms-excel',\n 'application/vnd.ms-powerpoint',\n 'application/zip',\n 'application/x-zip-compressed',\n 'application/octet-stream',\n 'image/',\n 'audio/',\n 'video/',\n ];\n\n // Check MIME type\n const isBinaryMimeType = binaryContentTypes.some((type) => contentType.includes(type));\n\n if (isBinaryMimeType) {\n return true;\n }\n\n // Check file extension as fallback\n const fileExt = filename.split('.').pop()?.toLowerCase() || '';\n\n // Text file extensions that should NOT be treated as binary\n const textExtensions = [\n 'txt',\n 'md',\n 'markdown',\n 'json',\n 'xml',\n 'html',\n 'htm',\n 'css',\n 'js',\n 'ts',\n 'jsx',\n 'tsx',\n 'yaml',\n 'yml',\n 'toml',\n 'ini',\n 'cfg',\n 'conf',\n 'sh',\n 'bash',\n 'zsh',\n 'fish',\n 'py',\n 'rb',\n 'go',\n 'rs',\n 'java',\n 'c',\n 'cpp',\n 'h',\n 'hpp',\n 'cs',\n 'php',\n 'sql',\n 'r',\n 'swift',\n 'kt',\n 'scala',\n 'clj',\n 'ex',\n 'exs',\n 'vim',\n 'env',\n 'gitignore',\n 'dockerignore',\n 'editorconfig',\n 'log',\n 'csv',\n 'tsv',\n 'properties',\n 'gradle',\n 'sbt',\n 'makefile',\n 'dockerfile',\n 'vagrantfile',\n 'gemfile',\n 'rakefile',\n 'podfile',\n 'csproj',\n 'vbproj',\n 'fsproj',\n 'sln',\n 'pom',\n ];\n\n // If it's a known text extension, it's not binary\n if (textExtensions.includes(fileExt)) {\n return false;\n }\n\n // Binary file extensions\n const binaryExtensions = [\n 'pdf',\n 'docx',\n 'doc',\n 'xls',\n 'xlsx',\n 'ppt',\n 'pptx',\n 'zip',\n 'rar',\n '7z',\n 'tar',\n 'gz',\n 'bz2',\n 'xz',\n 'jpg',\n 'jpeg',\n 'png',\n 'gif',\n 'bmp',\n 'svg',\n 'ico',\n 'webp',\n 'mp3',\n 'mp4',\n 'avi',\n 'mov',\n 'wmv',\n 'flv',\n 'wav',\n 'flac',\n 'ogg',\n 'exe',\n 'dll',\n 'so',\n 'dylib',\n 'bin',\n 'dat',\n 'db',\n 'sqlite',\n ];\n\n return binaryExtensions.includes(fileExt);\n}\n\n/**\n * Check if the input is a TextItem.\n *\n * @param item - The input item to check.\n * @returns A boolean indicating if the input is a TextItem.\n */\nfunction isTextItem(item: TextItem | TextMarkedContent): item is TextItem {\n return 'str' in item;\n}\n\n/**\n * Fetches content from a URL and converts it to base64 format\n * @param url The URL to fetch content from\n * @returns An object containing the base64 content and content type\n */\nexport async function fetchUrlContent(url: string): Promise<{ content: string; contentType: string }> {\n logger.debug(`[URL FETCHER] Fetching content from URL: ${url}`);\n \n try {\n // Fetch the URL with timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout\n \n const response = await fetch(url, { \n signal: controller.signal,\n headers: {\n 'User-Agent': 'Eliza-Knowledge-Plugin/1.0'\n }\n });\n clearTimeout(timeoutId);\n \n if (!response.ok) {\n throw new Error(`Failed to fetch URL: ${response.status} ${response.statusText}`);\n }\n \n // Get content type from response headers\n const contentType = response.headers.get('content-type') || 'application/octet-stream';\n logger.debug(`[URL FETCHER] Content type from server: ${contentType} for URL: ${url}`);\n \n // Get content as ArrayBuffer\n const arrayBuffer = await response.arrayBuffer();\n const buffer = Buffer.from(arrayBuffer);\n \n // Convert to base64\n const base64Content = buffer.toString('base64');\n \n logger.debug(`[URL FETCHER] Successfully fetched content from URL: ${url} (${buffer.length} bytes)`);\n return {\n content: base64Content,\n contentType\n };\n } catch (error: any) {\n logger.error(`[URL FETCHER] Error fetching content from URL ${url}: ${error.message}`);\n throw new Error(`Failed to fetch content from URL: ${error.message}`);\n }\n}\n"],"mappings":"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","names":["logger","logger"]}
1
+ {"version":3,"sources":["../src/docs-loader.ts","../src/utils.ts"],"sourcesContent":["import { logger, UUID, createUniqueUuid } from \"@elizaos/core\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { KnowledgeService } from \"./service.ts\";\nimport { AddKnowledgeOptions } from \"./types.ts\";\nimport { isBinaryContentType } from './utils.ts';\n\n/**\n * Get the knowledge path from environment or default to ./docs\n */\nexport function getKnowledgePath(): string {\n const envPath = process.env.KNOWLEDGE_PATH;\n\n if (envPath) {\n // Resolve relative paths from current working directory\n const resolvedPath = path.resolve(envPath);\n\n if (!fs.existsSync(resolvedPath)) {\n logger.warn(`Knowledge path from environment variable does not exist: ${resolvedPath}`);\n logger.warn('Please create the directory or update KNOWLEDGE_PATH environment variable');\n }\n\n return resolvedPath;\n }\n\n // Default to docs folder in current working directory\n const defaultPath = path.join(process.cwd(), 'docs');\n\n if (!fs.existsSync(defaultPath)) {\n logger.info(`Default docs folder does not exist at: ${defaultPath}`);\n logger.info('To use the knowledge plugin, either:');\n logger.info('1. Create a \"docs\" folder in your project root');\n logger.info('2. Set KNOWLEDGE_PATH environment variable to your documents folder');\n }\n\n return defaultPath;\n}\n\n/**\n * Load documents from the knowledge path\n */\nexport async function loadDocsFromPath(\n service: KnowledgeService,\n agentId: UUID,\n worldId?: UUID\n): Promise<{ total: number; successful: number; failed: number }> {\n const docsPath = getKnowledgePath();\n\n if (!fs.existsSync(docsPath)) {\n logger.warn(`Knowledge path does not exist: ${docsPath}`);\n return { total: 0, successful: 0, failed: 0 };\n }\n\n logger.info(`Loading documents from: ${docsPath}`);\n\n // Get all files recursively\n const files = getAllFiles(docsPath);\n\n if (files.length === 0) {\n logger.info('No files found in knowledge path');\n return { total: 0, successful: 0, failed: 0 };\n }\n\n logger.info(`Found ${files.length} files to process`);\n\n let successful = 0;\n let failed = 0;\n\n for (const filePath of files) {\n try {\n const fileName = path.basename(filePath);\n const fileExt = path.extname(filePath).toLowerCase();\n\n // Skip hidden files and directories\n if (fileName.startsWith('.')) {\n continue;\n }\n\n // Determine content type\n const contentType = getContentType(fileExt);\n\n // Skip unsupported file types\n if (!contentType) {\n logger.debug(`Skipping unsupported file type: ${filePath}`);\n continue;\n }\n\n // Read file\n const fileBuffer = fs.readFileSync(filePath);\n\n // Check if file is binary using the same logic as the service\n const isBinary = isBinaryContentType(contentType, fileName);\n\n // For text files, read as UTF-8 string directly\n // For binary files, convert to base64\n const content = isBinary ? fileBuffer.toString('base64') : fileBuffer.toString('utf-8');\n\n // Create knowledge options\n const knowledgeOptions: AddKnowledgeOptions = {\n clientDocumentId: createUniqueUuid(agentId, `docs-${fileName}-${Date.now()}`) as UUID,\n contentType,\n originalFilename: fileName,\n worldId: worldId || agentId,\n content,\n roomId: agentId,\n entityId: agentId,\n };\n\n // Process the document\n logger.debug(`Processing document: ${fileName}`);\n const result = await service.addKnowledge(knowledgeOptions);\n\n logger.info(`Successfully processed ${fileName}: ${result.fragmentCount} fragments created`);\n successful++;\n } catch (error) {\n logger.error(`Failed to process file ${filePath}:`, error);\n failed++;\n }\n }\n\n logger.info(\n `Document loading complete: ${successful} successful, ${failed} failed out of ${files.length} total`\n );\n\n return {\n total: files.length,\n successful,\n failed,\n };\n}\n\n/**\n * Recursively get all files in a directory\n */\nfunction getAllFiles(dirPath: string, files: string[] = []): string[] {\n try {\n const entries = fs.readdirSync(dirPath, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dirPath, entry.name);\n\n if (entry.isDirectory()) {\n // Skip node_modules and other common directories\n if (!['node_modules', '.git', '.vscode', 'dist', 'build'].includes(entry.name)) {\n getAllFiles(fullPath, files);\n }\n } else if (entry.isFile()) {\n files.push(fullPath);\n }\n }\n } catch (error) {\n logger.error(`Error reading directory ${dirPath}:`, error);\n }\n\n return files;\n}\n\n/**\n * Get content type based on file extension\n */\nfunction getContentType(extension: string): string | null {\n const contentTypes: Record<string, string> = {\n // Text documents\n '.txt': 'text/plain',\n '.md': 'text/markdown',\n '.markdown': 'text/markdown',\n '.tson': 'text/plain',\n '.xml': 'application/xml',\n '.csv': 'text/csv',\n '.tsv': 'text/tab-separated-values',\n '.log': 'text/plain',\n\n // Web files\n '.html': 'text/html',\n '.htm': 'text/html',\n '.css': 'text/css',\n '.scss': 'text/x-scss',\n '.sass': 'text/x-sass',\n '.less': 'text/x-less',\n\n // JavaScript/TypeScript\n '.js': 'text/javascript',\n '.jsx': 'text/javascript',\n '.ts': 'text/typescript',\n '.tsx': 'text/typescript',\n '.mjs': 'text/javascript',\n '.cjs': 'text/javascript',\n '.vue': 'text/x-vue',\n '.svelte': 'text/x-svelte',\n '.astro': 'text/x-astro',\n\n // Python\n '.py': 'text/x-python',\n '.pyw': 'text/x-python',\n '.pyi': 'text/x-python',\n\n // Java/Kotlin/Scala\n '.java': 'text/x-java',\n '.kt': 'text/x-kotlin',\n '.kts': 'text/x-kotlin',\n '.scala': 'text/x-scala',\n\n // C/C++/C#\n '.c': 'text/x-c',\n '.cpp': 'text/x-c++',\n '.cc': 'text/x-c++',\n '.cxx': 'text/x-c++',\n '.h': 'text/x-c',\n '.hpp': 'text/x-c++',\n '.cs': 'text/x-csharp',\n\n // Other languages\n '.php': 'text/x-php',\n '.rb': 'text/x-ruby',\n '.go': 'text/x-go',\n '.rs': 'text/x-rust',\n '.swift': 'text/x-swift',\n '.r': 'text/x-r',\n '.R': 'text/x-r',\n '.m': 'text/x-objectivec',\n '.mm': 'text/x-objectivec',\n '.clj': 'text/x-clojure',\n '.cljs': 'text/x-clojure',\n '.ex': 'text/x-elixir',\n '.exs': 'text/x-elixir',\n '.lua': 'text/x-lua',\n '.pl': 'text/x-perl',\n '.pm': 'text/x-perl',\n '.dart': 'text/x-dart',\n '.hs': 'text/x-haskell',\n '.elm': 'text/x-elm',\n '.ml': 'text/x-ocaml',\n '.fs': 'text/x-fsharp',\n '.fsx': 'text/x-fsharp',\n '.vb': 'text/x-vb',\n '.pas': 'text/x-pascal',\n '.d': 'text/x-d',\n '.nim': 'text/x-nim',\n '.zig': 'text/x-zig',\n '.jl': 'text/x-julia',\n '.tcl': 'text/x-tcl',\n '.awk': 'text/x-awk',\n '.sed': 'text/x-sed',\n\n // Shell scripts\n '.sh': 'text/x-sh',\n '.bash': 'text/x-sh',\n '.zsh': 'text/x-sh',\n '.fish': 'text/x-fish',\n '.ps1': 'text/x-powershell',\n '.bat': 'text/x-batch',\n '.cmd': 'text/x-batch',\n\n // Config files\n '.json': 'application/json',\n '.yaml': 'text/x-yaml',\n '.yml': 'text/x-yaml',\n '.toml': 'text/x-toml',\n '.ini': 'text/x-ini',\n '.cfg': 'text/x-ini',\n '.conf': 'text/x-ini',\n '.env': 'text/plain',\n '.gitignore': 'text/plain',\n '.dockerignore': 'text/plain',\n '.editorconfig': 'text/plain',\n '.properties': 'text/x-properties',\n\n // Database\n '.sql': 'text/x-sql',\n\n // Binary documents\n '.pdf': 'application/pdf',\n '.doc': 'application/msword',\n '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n };\n\n return contentTypes[extension] || null;\n}\n","import { Buffer } from 'node:buffer';\nimport * as mammoth from 'mammoth';\nimport { logger } from '@elizaos/core';\nimport { getDocument, PDFDocumentProxy } from 'pdfjs-dist/legacy/build/pdf.mjs';\nimport type { TextItem, TextMarkedContent } from 'pdfjs-dist/types/src/display/api';\n\nconst PLAIN_TEXT_CONTENT_TYPES = [\n 'application/typescript',\n 'text/typescript',\n 'text/x-python',\n 'application/x-python-code',\n 'application/yaml',\n 'text/yaml',\n 'application/x-yaml',\n 'application/json',\n 'text/markdown',\n 'text/csv',\n];\n\nconst MAX_FALLBACK_SIZE_BYTES = 5 * 1024 * 1024; // 5 MB\nconst BINARY_CHECK_BYTES = 1024; // Check first 1KB for binary indicators\n\n/**\n * Extracts text content from a file buffer based on its content type.\n * Supports DOCX, plain text, and provides a fallback for unknown types.\n * PDF should be handled by `convertPdfToTextFromBuffer`.\n */\nexport async function extractTextFromFileBuffer(\n fileBuffer: Buffer,\n contentType: string,\n originalFilename: string // For logging and context\n): Promise<string> {\n const lowerContentType = contentType.toLowerCase();\n logger.debug(\n `[TextUtil] Attempting to extract text from ${originalFilename} (type: ${contentType})`\n );\n\n if (\n lowerContentType === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'\n ) {\n logger.debug(`[TextUtil] Extracting text from DOCX ${originalFilename} via mammoth.`);\n try {\n const result = await mammoth.extractRawText({ buffer: fileBuffer });\n logger.debug(\n `[TextUtil] DOCX text extraction complete for ${originalFilename}. Text length: ${result.value.length}`\n );\n return result.value;\n } catch (docxError: any) {\n const errorMsg = `[TextUtil] Failed to parse DOCX file ${originalFilename}: ${docxError.message}`;\n logger.error(errorMsg, docxError.stack);\n throw new Error(errorMsg);\n }\n } else if (\n lowerContentType === 'application/msword' ||\n originalFilename.toLowerCase().endsWith('.doc')\n ) {\n // For .doc files, we'll store the content as-is, and just add a message\n // The frontend will handle the display appropriately\n logger.debug(`[TextUtil] Handling Microsoft Word .doc file: ${originalFilename}`);\n\n // We'll add a descriptive message as a placeholder\n return `[Microsoft Word Document: ${originalFilename}]\\n\\nThis document was indexed for search but cannot be displayed directly in the browser. The original document content is preserved for retrieval purposes.`;\n } else if (\n lowerContentType.startsWith('text/') ||\n PLAIN_TEXT_CONTENT_TYPES.includes(lowerContentType)\n ) {\n logger.debug(\n `[TextUtil] Extracting text from plain text compatible file ${originalFilename} (type: ${contentType})`\n );\n return fileBuffer.toString('utf-8');\n } else {\n logger.warn(\n `[TextUtil] Unsupported content type: \"${contentType}\" for ${originalFilename}. Attempting fallback to plain text.`\n );\n\n if (fileBuffer.length > MAX_FALLBACK_SIZE_BYTES) {\n const sizeErrorMsg = `[TextUtil] File ${originalFilename} (type: ${contentType}) exceeds maximum size for fallback (${MAX_FALLBACK_SIZE_BYTES} bytes). Cannot process as plain text.`;\n logger.error(sizeErrorMsg);\n throw new Error(sizeErrorMsg);\n }\n\n // Simple binary detection: check for null bytes in the first N bytes\n const initialBytes = fileBuffer.subarray(0, Math.min(fileBuffer.length, BINARY_CHECK_BYTES));\n if (initialBytes.includes(0)) {\n // Check for NUL byte\n const binaryHeuristicMsg = `[TextUtil] File ${originalFilename} (type: ${contentType}) appears to be binary based on initial byte check. Cannot process as plain text.`;\n logger.error(binaryHeuristicMsg);\n throw new Error(binaryHeuristicMsg);\n }\n\n try {\n const textContent = fileBuffer.toString('utf-8');\n if (textContent.includes('\\ufffd')) {\n // Replacement character, indicating potential binary or wrong encoding\n const binaryErrorMsg = `[TextUtil] File ${originalFilename} (type: ${contentType}) seems to be binary or has encoding issues after fallback to plain text (detected \\ufffd).`;\n logger.error(binaryErrorMsg);\n throw new Error(binaryErrorMsg); // Throw error for likely binary content\n }\n logger.debug(\n `[TextUtil] Successfully processed unknown type ${contentType} as plain text after fallback for ${originalFilename}.`\n );\n return textContent;\n } catch (fallbackError: any) {\n // If the initial toString failed or if we threw due to \\ufffd\n const finalErrorMsg = `[TextUtil] Unsupported content type: ${contentType} for ${originalFilename}. Fallback to plain text also failed or indicated binary content.`;\n logger.error(finalErrorMsg, fallbackError.message ? fallbackError.stack : undefined);\n throw new Error(finalErrorMsg);\n }\n }\n}\n\n/**\n * Converts a PDF file buffer to text content.\n * Requires pdfjs-dist to be properly configured, especially its worker.\n */\n/**\n * Converts a PDF Buffer to text with enhanced formatting preservation.\n *\n * @param {Buffer} pdfBuffer - The PDF Buffer to convert to text\n * @param {string} [filename] - Optional filename for logging purposes\n * @returns {Promise<string>} Text content of the PDF\n */\nexport async function convertPdfToTextFromBuffer(\n pdfBuffer: Buffer,\n filename?: string\n): Promise<string> {\n const docName = filename || 'unnamed-document';\n logger.debug(`[PdfService] Starting conversion for ${docName}`);\n\n try {\n const uint8Array = new Uint8Array(pdfBuffer);\n const pdf: PDFDocumentProxy = await getDocument({ data: uint8Array }).promise;\n const numPages = pdf.numPages;\n const textPages: string[] = [];\n\n for (let pageNum = 1; pageNum <= numPages; pageNum++) {\n logger.debug(`[PdfService] Processing page ${pageNum}/${numPages}`);\n const page = await pdf.getPage(pageNum);\n const textContent = await page.getTextContent();\n\n // Group text items by their y-position to maintain line structure\n const lineMap = new Map<number, TextItem[]>();\n\n textContent.items.filter(isTextItem).forEach((item) => {\n // Round y-position to account for small variations in the same line\n const yPos = Math.round(item.transform[5]);\n if (!lineMap.has(yPos)) {\n lineMap.set(yPos, []);\n }\n lineMap.get(yPos)!.push(item);\n });\n\n // Sort lines by y-position (top to bottom) and items within lines by x-position (left to right)\n const sortedLines = Array.from(lineMap.entries())\n .sort((a, b) => b[0] - a[0]) // Reverse sort for top-to-bottom\n .map(([_, items]) =>\n items\n .sort((a, b) => a.transform[4] - b.transform[4])\n .map((item) => item.str)\n .join(' ')\n );\n\n textPages.push(sortedLines.join('\\n'));\n }\n\n const fullText = textPages.join('\\n\\n').replace(/\\s+/g, ' ').trim();\n logger.debug(`[PdfService] Conversion complete for ${docName}, length: ${fullText.length}`);\n return fullText;\n } catch (error: any) {\n logger.error(`[PdfService] Error converting PDF ${docName}:`, error.message);\n throw new Error(`Failed to convert PDF to text: ${error.message}`);\n }\n}\n\n/**\n * Determines if a file should be treated as binary based on its content type and filename\n * @param contentType MIME type of the file\n * @param filename Original filename\n * @returns True if the file should be treated as binary (base64 encoded)\n */\nexport function isBinaryContentType(contentType: string, filename: string): boolean {\n // Text-based content types that should NOT be treated as binary\n const textContentTypes = [\n 'text/',\n 'application/json',\n 'application/xml',\n 'application/javascript',\n 'application/typescript',\n 'application/x-yaml',\n 'application/x-sh',\n ];\n\n // Check if it's a text-based MIME type\n const isTextMimeType = textContentTypes.some((type) => contentType.includes(type));\n if (isTextMimeType) {\n return false;\n }\n\n // Binary content types\n const binaryContentTypes = [\n 'application/pdf',\n 'application/msword',\n 'application/vnd.openxmlformats-officedocument',\n 'application/vnd.ms-excel',\n 'application/vnd.ms-powerpoint',\n 'application/zip',\n 'application/x-zip-compressed',\n 'application/octet-stream',\n 'image/',\n 'audio/',\n 'video/',\n ];\n\n // Check MIME type\n const isBinaryMimeType = binaryContentTypes.some((type) => contentType.includes(type));\n\n if (isBinaryMimeType) {\n return true;\n }\n\n // Check file extension as fallback\n const fileExt = filename.split('.').pop()?.toLowerCase() || '';\n\n // Text file extensions that should NOT be treated as binary\n const textExtensions = [\n 'txt',\n 'md',\n 'markdown',\n 'json',\n 'xml',\n 'html',\n 'htm',\n 'css',\n 'js',\n 'ts',\n 'jsx',\n 'tsx',\n 'yaml',\n 'yml',\n 'toml',\n 'ini',\n 'cfg',\n 'conf',\n 'sh',\n 'bash',\n 'zsh',\n 'fish',\n 'py',\n 'rb',\n 'go',\n 'rs',\n 'java',\n 'c',\n 'cpp',\n 'h',\n 'hpp',\n 'cs',\n 'php',\n 'sql',\n 'r',\n 'swift',\n 'kt',\n 'scala',\n 'clj',\n 'ex',\n 'exs',\n 'vim',\n 'env',\n 'gitignore',\n 'dockerignore',\n 'editorconfig',\n 'log',\n 'csv',\n 'tsv',\n 'properties',\n 'gradle',\n 'sbt',\n 'makefile',\n 'dockerfile',\n 'vagrantfile',\n 'gemfile',\n 'rakefile',\n 'podfile',\n 'csproj',\n 'vbproj',\n 'fsproj',\n 'sln',\n 'pom',\n ];\n\n // If it's a known text extension, it's not binary\n if (textExtensions.includes(fileExt)) {\n return false;\n }\n\n // Binary file extensions\n const binaryExtensions = [\n 'pdf',\n 'docx',\n 'doc',\n 'xls',\n 'xlsx',\n 'ppt',\n 'pptx',\n 'zip',\n 'rar',\n '7z',\n 'tar',\n 'gz',\n 'bz2',\n 'xz',\n 'jpg',\n 'jpeg',\n 'png',\n 'gif',\n 'bmp',\n 'svg',\n 'ico',\n 'webp',\n 'mp3',\n 'mp4',\n 'avi',\n 'mov',\n 'wmv',\n 'flv',\n 'wav',\n 'flac',\n 'ogg',\n 'exe',\n 'dll',\n 'so',\n 'dylib',\n 'bin',\n 'dat',\n 'db',\n 'sqlite',\n ];\n\n return binaryExtensions.includes(fileExt);\n}\n\n/**\n * Check if the input is a TextItem.\n *\n * @param item - The input item to check.\n * @returns A boolean indicating if the input is a TextItem.\n */\nfunction isTextItem(item: TextItem | TextMarkedContent): item is TextItem {\n return 'str' in item;\n}\n\n/**\n * Normalizes an S3 URL by removing query parameters (signature, etc.)\n * This allows for consistent URL comparison regardless of presigned URL parameters\n * @param url The S3 URL to normalize\n * @returns The normalized URL containing only the origin and pathname\n */\nexport function normalizeS3Url(url: string): string {\n try {\n const urlObj = new URL(url);\n return `${urlObj.origin}${urlObj.pathname}`;\n } catch (error) {\n logger.warn(`[URL NORMALIZER] Failed to parse URL: ${url}. Returning original.`);\n return url;\n }\n}\n\n/**\n * Fetches content from a URL and converts it to base64 format\n * @param url The URL to fetch content from\n * @returns An object containing the base64 content and content type\n */\nexport async function fetchUrlContent(url: string): Promise<{ content: string; contentType: string }> {\n logger.debug(`[URL FETCHER] Fetching content from URL: ${url}`);\n \n try {\n // Fetch the URL with timeout\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout\n \n const response = await fetch(url, { \n signal: controller.signal,\n headers: {\n 'User-Agent': 'Eliza-Knowledge-Plugin/1.0'\n }\n });\n clearTimeout(timeoutId);\n \n if (!response.ok) {\n throw new Error(`Failed to fetch URL: ${response.status} ${response.statusText}`);\n }\n \n // Get content type from response headers\n const contentType = response.headers.get('content-type') || 'application/octet-stream';\n logger.debug(`[URL FETCHER] Content type from server: ${contentType} for URL: ${url}`);\n \n // Get content as ArrayBuffer\n const arrayBuffer = await response.arrayBuffer();\n const buffer = Buffer.from(arrayBuffer);\n \n // Convert to base64\n const base64Content = buffer.toString('base64');\n \n logger.debug(`[URL FETCHER] Successfully fetched content from URL: ${url} (${buffer.length} bytes)`);\n return {\n content: base64Content,\n contentType\n };\n } catch (error: any) {\n logger.error(`[URL FETCHER] Error fetching content from URL ${url}: ${error.message}`);\n throw new Error(`Failed to fetch content from URL: ${error.message}`);\n }\n}\n"],"mappings":"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","names":["logger","logger"]}
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  getKnowledgePath,
3
3
  loadDocsFromPath
4
- } from "./chunk-HUTF5APY.js";
4
+ } from "./chunk-BB6B27BS.js";
5
5
  export {
6
6
  getKnowledgePath,
7
7
  loadDocsFromPath
8
8
  };
9
- //# sourceMappingURL=docs-loader-2S6H7F4L.js.map
9
+ //# sourceMappingURL=docs-loader-NAE6ASGY.js.map
package/dist/index.d.ts CHANGED
@@ -156,6 +156,26 @@ interface LoadResult {
156
156
  error: string;
157
157
  }>;
158
158
  }
159
+ /**
160
+ * Extends the base MemoryMetadata from @elizaos/core with additional fields
161
+ */
162
+ interface ExtendedMemoryMetadata extends Record<string, any> {
163
+ type?: string;
164
+ title?: string;
165
+ filename?: string;
166
+ path?: string;
167
+ description?: string;
168
+ fileExt?: string;
169
+ timestamp?: number;
170
+ contentType?: string;
171
+ documentId?: string;
172
+ source?: string;
173
+ fileType?: string;
174
+ fileSize?: number;
175
+ position?: number;
176
+ originalFilename?: string;
177
+ url?: string;
178
+ }
159
179
 
160
180
  /**
161
181
  * Knowledge Plugin - Main Entry Point
@@ -168,4 +188,4 @@ interface LoadResult {
168
188
  */
169
189
  declare const knowledgePlugin: Plugin;
170
190
 
171
- export { type AddKnowledgeOptions, type KnowledgeConfig, type KnowledgeDocumentMetadata, KnowledgeServiceType, type LoadResult, type ModelConfig, ModelConfigSchema, type ProviderRateLimits, type TextGenerationOptions, knowledgePlugin as default, knowledgePlugin };
191
+ export { type AddKnowledgeOptions, type ExtendedMemoryMetadata, type KnowledgeConfig, type KnowledgeDocumentMetadata, KnowledgeServiceType, type LoadResult, type ModelConfig, ModelConfigSchema, type ProviderRateLimits, type TextGenerationOptions, knowledgePlugin as default, knowledgePlugin };
package/dist/index.html CHANGED
@@ -5,8 +5,8 @@
5
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Agent Plugin View</title>
8
- <script type="module" crossorigin src="./assets/index-D30O9PiT.js"></script>
9
- <link rel="stylesheet" crossorigin href="./assets/index-BdT7VEOH.css">
8
+ <script type="module" crossorigin src="./assets/index-BRhhNXdt.js"></script>
9
+ <link rel="stylesheet" crossorigin href="./assets/index-Clk6Xgn1.css">
10
10
  </head>
11
11
  <body>
12
12
  <div id="root"></div>
package/dist/index.js CHANGED
@@ -3,8 +3,9 @@ import {
3
3
  extractTextFromFileBuffer,
4
4
  fetchUrlContent,
5
5
  isBinaryContentType,
6
- loadDocsFromPath
7
- } from "./chunk-HUTF5APY.js";
6
+ loadDocsFromPath,
7
+ normalizeS3Url
8
+ } from "./chunk-BB6B27BS.js";
8
9
 
9
10
  // src/index.ts
10
11
  import { logger as logger6 } from "@elizaos/core";
@@ -121,12 +122,6 @@ function validateConfigRequirements(config, assumePluginOpenAI) {
121
122
  }
122
123
  if (config.CTX_KNOWLEDGE_ENABLED) {
123
124
  logger.info("Contextual Knowledge is enabled. Validating text generation settings...");
124
- if (!config.TEXT_PROVIDER) {
125
- throw new Error("TEXT_PROVIDER is required when CTX_KNOWLEDGE_ENABLED is true");
126
- }
127
- if (!config.TEXT_MODEL) {
128
- throw new Error("TEXT_MODEL is required when CTX_KNOWLEDGE_ENABLED is true");
129
- }
130
125
  if (config.TEXT_PROVIDER === "openai" && !config.OPENAI_API_KEY) {
131
126
  throw new Error('OPENAI_API_KEY is required when TEXT_PROVIDER is set to "openai"');
132
127
  }
@@ -709,26 +704,17 @@ async function processFragmentsSynchronously({
709
704
  worldId
710
705
  }) {
711
706
  if (!fullDocumentText || fullDocumentText.trim() === "") {
712
- logger2.warn(
713
- `No text content available to chunk for document ${documentId}.`
714
- );
707
+ logger2.warn(`No text content available to chunk for document ${documentId}.`);
715
708
  return 0;
716
709
  }
717
710
  const chunks = await splitDocumentIntoChunks(fullDocumentText);
718
711
  if (chunks.length === 0) {
719
- logger2.warn(
720
- `No chunks generated from text for ${documentId}. No fragments to save.`
721
- );
712
+ logger2.warn(`No chunks generated from text for ${documentId}. No fragments to save.`);
722
713
  return 0;
723
714
  }
724
- logger2.info(
725
- `Split content into ${chunks.length} chunks for document ${documentId}`
726
- );
715
+ logger2.info(`Split content into ${chunks.length} chunks for document ${documentId}`);
727
716
  const providerLimits = await getProviderRateLimits();
728
- const CONCURRENCY_LIMIT = Math.min(
729
- 30,
730
- providerLimits.maxConcurrentRequests || 30
731
- );
717
+ const CONCURRENCY_LIMIT = Math.min(30, providerLimits.maxConcurrentRequests || 30);
732
718
  const rateLimiter = createRateLimiter(providerLimits.requestsPerMinute || 60);
733
719
  const { savedCount, failedCount } = await processAndSaveFragments({
734
720
  runtime,
@@ -748,25 +734,19 @@ async function processFragmentsSynchronously({
748
734
  `Failed to process ${failedCount} chunks out of ${chunks.length} for document ${documentId}`
749
735
  );
750
736
  }
751
- logger2.info(
752
- `Finished saving ${savedCount} fragments for document ${documentId}.`
753
- );
737
+ logger2.info(`Finished saving ${savedCount} fragments for document ${documentId}.`);
754
738
  return savedCount;
755
739
  }
756
740
  async function extractTextFromDocument(fileBuffer, contentType, originalFilename) {
757
741
  if (!fileBuffer || fileBuffer.length === 0) {
758
- throw new Error(
759
- `Empty file buffer provided for ${originalFilename}. Cannot extract text.`
760
- );
742
+ throw new Error(`Empty file buffer provided for ${originalFilename}. Cannot extract text.`);
761
743
  }
762
744
  try {
763
745
  if (contentType === "application/pdf") {
764
746
  logger2.debug(`Extracting text from PDF: ${originalFilename}`);
765
747
  return await convertPdfToTextFromBuffer(fileBuffer, originalFilename);
766
748
  } else {
767
- logger2.debug(
768
- `Extracting text from non-PDF: ${originalFilename} (Type: ${contentType})`
769
- );
749
+ logger2.debug(`Extracting text from non-PDF: ${originalFilename} (Type: ${contentType})`);
770
750
  if (contentType.includes("text/") || contentType.includes("application/json") || contentType.includes("application/xml")) {
771
751
  try {
772
752
  return fileBuffer.toString("utf8");
@@ -776,19 +756,11 @@ async function extractTextFromDocument(fileBuffer, contentType, originalFilename
776
756
  );
777
757
  }
778
758
  }
779
- return await extractTextFromFileBuffer(
780
- fileBuffer,
781
- contentType,
782
- originalFilename
783
- );
759
+ return await extractTextFromFileBuffer(fileBuffer, contentType, originalFilename);
784
760
  }
785
761
  } catch (error) {
786
- logger2.error(
787
- `Error extracting text from ${originalFilename}: ${error.message}`
788
- );
789
- throw new Error(
790
- `Failed to extract text from ${originalFilename}: ${error.message}`
791
- );
762
+ logger2.error(`Error extracting text from ${originalFilename}: ${error.message}`);
763
+ throw new Error(`Failed to extract text from ${originalFilename}: ${error.message}`);
792
764
  }
793
765
  }
794
766
  function createDocumentMemory({
@@ -799,7 +771,8 @@ function createDocumentMemory({
799
771
  contentType,
800
772
  worldId,
801
773
  fileSize,
802
- documentId
774
+ documentId,
775
+ customMetadata
803
776
  }) {
804
777
  const fileExt = originalFilename.split(".").pop()?.toLowerCase() || "";
805
778
  const title = originalFilename.replace(`.${fileExt}`, "");
@@ -820,19 +793,17 @@ function createDocumentMemory({
820
793
  fileExt,
821
794
  fileSize,
822
795
  source: "rag-service-main-upload",
823
- timestamp: Date.now()
796
+ timestamp: Date.now(),
797
+ // Merge custom metadata if provided
798
+ ...customMetadata || {}
824
799
  }
825
800
  };
826
801
  }
827
802
  async function splitDocumentIntoChunks(documentText) {
828
803
  const tokenChunkSize = DEFAULT_CHUNK_TOKEN_SIZE;
829
804
  const tokenChunkOverlap = DEFAULT_CHUNK_OVERLAP_TOKENS;
830
- const targetCharChunkSize = Math.round(
831
- tokenChunkSize * DEFAULT_CHARS_PER_TOKEN
832
- );
833
- const targetCharChunkOverlap = Math.round(
834
- tokenChunkOverlap * DEFAULT_CHARS_PER_TOKEN
835
- );
805
+ const targetCharChunkSize = Math.round(tokenChunkSize * DEFAULT_CHARS_PER_TOKEN);
806
+ const targetCharChunkOverlap = Math.round(tokenChunkOverlap * DEFAULT_CHARS_PER_TOKEN);
836
807
  logger2.debug(
837
808
  `Using core splitChunks with settings: tokenChunkSize=${tokenChunkSize}, tokenChunkOverlap=${tokenChunkOverlap}, charChunkSize=${targetCharChunkSize}, charChunkOverlap=${targetCharChunkOverlap}`
838
809
  );
@@ -856,10 +827,7 @@ async function processAndSaveFragments({
856
827
  const failedChunks = [];
857
828
  for (let i = 0; i < chunks.length; i += concurrencyLimit) {
858
829
  const batchChunks = chunks.slice(i, i + concurrencyLimit);
859
- const batchOriginalIndices = Array.from(
860
- { length: batchChunks.length },
861
- (_, k) => i + k
862
- );
830
+ const batchOriginalIndices = Array.from({ length: batchChunks.length }, (_, k) => i + k);
863
831
  logger2.debug(
864
832
  `Processing batch of ${batchChunks.length} chunks for document ${documentId}. Starting original index: ${batchOriginalIndices[0]}, batch ${Math.floor(i / concurrencyLimit) + 1}/${Math.ceil(chunks.length / concurrencyLimit)}`
865
833
  );
@@ -880,9 +848,7 @@ async function processAndSaveFragments({
880
848
  if (!result.success) {
881
849
  failedCount++;
882
850
  failedChunks.push(originalChunkIndex);
883
- logger2.warn(
884
- `Failed to process chunk ${originalChunkIndex} for document ${documentId}`
885
- );
851
+ logger2.warn(`Failed to process chunk ${originalChunkIndex} for document ${documentId}`);
886
852
  continue;
887
853
  }
888
854
  const contextualizedChunkText = result.text;
@@ -1002,9 +968,6 @@ async function generateContextsInBatch(runtime, fullDocumentText, chunks, conten
1002
968
  const config = validateModelConfig();
1003
969
  const isUsingOpenRouter = config.TEXT_PROVIDER === "openrouter";
1004
970
  const isUsingCacheCapableModel = isUsingOpenRouter && (config.TEXT_MODEL?.toLowerCase().includes("claude") || config.TEXT_MODEL?.toLowerCase().includes("gemini"));
1005
- logger2.info(
1006
- `Using provider: ${config.TEXT_PROVIDER}, model: ${config.TEXT_MODEL}, caching capability: ${isUsingCacheCapableModel}`
1007
- );
1008
971
  const promptConfigs = prepareContextPrompts(
1009
972
  chunks,
1010
973
  fullDocumentText,
@@ -1043,10 +1006,7 @@ async function generateContextsInBatch(runtime, fullDocumentText, chunks, conten
1043
1006
  `context generation for chunk ${item.originalIndex}`
1044
1007
  );
1045
1008
  const generatedContext = llmResponse.text;
1046
- const contextualizedText = getChunkWithContext(
1047
- item.chunkText,
1048
- generatedContext
1049
- );
1009
+ const contextualizedText = getChunkWithContext(item.chunkText, generatedContext);
1050
1010
  logger2.debug(
1051
1011
  `Context added for chunk ${item.originalIndex}. New length: ${contextualizedText.length}`
1052
1012
  );
@@ -1099,9 +1059,7 @@ function prepareContextPrompts(chunks, fullDocumentText, contentType, batchIndic
1099
1059
  } else {
1100
1060
  const prompt = contentType ? getPromptForMimeType(contentType, fullDocumentText, chunkText) : getContextualizationPrompt(fullDocumentText, chunkText);
1101
1061
  if (prompt.startsWith("Error:")) {
1102
- logger2.warn(
1103
- `Skipping contextualization for chunk ${originalIndex} due to: ${prompt}`
1104
- );
1062
+ logger2.warn(`Skipping contextualization for chunk ${originalIndex} due to: ${prompt}`);
1105
1063
  return {
1106
1064
  prompt: null,
1107
1065
  originalIndex,
@@ -1140,9 +1098,7 @@ async function generateEmbeddingWithValidation(runtime, text) {
1140
1098
  });
1141
1099
  const embedding = Array.isArray(embeddingResult) ? embeddingResult : embeddingResult?.embedding;
1142
1100
  if (!embedding || embedding.length === 0) {
1143
- logger2.warn(
1144
- `Zero vector detected. Embedding result: ${JSON.stringify(embeddingResult)}`
1145
- );
1101
+ logger2.warn(`Zero vector detected. Embedding result: ${JSON.stringify(embeddingResult)}`);
1146
1102
  return {
1147
1103
  embedding: null,
1148
1104
  success: false,
@@ -1160,16 +1116,12 @@ async function withRateLimitRetry(operation, errorContext, retryDelay) {
1160
1116
  } catch (error) {
1161
1117
  if (error.status === 429) {
1162
1118
  const delay = retryDelay || error.headers?.["retry-after"] || 5;
1163
- logger2.warn(
1164
- `Rate limit hit for ${errorContext}. Retrying after ${delay}s`
1165
- );
1119
+ logger2.warn(`Rate limit hit for ${errorContext}. Retrying after ${delay}s`);
1166
1120
  await new Promise((resolve) => setTimeout(resolve, delay * 1e3));
1167
1121
  try {
1168
1122
  return await operation();
1169
1123
  } catch (retryError) {
1170
- logger2.error(
1171
- `Failed after retry for ${errorContext}: ${retryError.message}`
1172
- );
1124
+ logger2.error(`Failed after retry for ${errorContext}: ${retryError.message}`);
1173
1125
  throw retryError;
1174
1126
  }
1175
1127
  }
@@ -1188,9 +1140,7 @@ function createRateLimiter(requestsPerMinute) {
1188
1140
  const oldestRequest = requestTimes[0];
1189
1141
  const timeToWait = Math.max(0, oldestRequest + intervalMs - now);
1190
1142
  if (timeToWait > 0) {
1191
- logger2.debug(
1192
- `Rate limiting applied, waiting ${timeToWait}ms before next request`
1193
- );
1143
+ logger2.debug(`Rate limiting applied, waiting ${timeToWait}ms before next request`);
1194
1144
  await new Promise((resolve) => setTimeout(resolve, timeToWait));
1195
1145
  }
1196
1146
  }
@@ -1353,7 +1303,8 @@ var KnowledgeService = class _KnowledgeService extends Service {
1353
1303
  worldId,
1354
1304
  content,
1355
1305
  roomId,
1356
- entityId
1306
+ entityId,
1307
+ metadata
1357
1308
  }) {
1358
1309
  const agentId = this.runtime.agentId;
1359
1310
  try {
@@ -1432,8 +1383,10 @@ var KnowledgeService = class _KnowledgeService extends Service {
1432
1383
  contentType,
1433
1384
  worldId,
1434
1385
  fileSize: fileBuffer ? fileBuffer.length : extractedText.length,
1435
- documentId: clientDocumentId
1386
+ documentId: clientDocumentId,
1436
1387
  // Explicitly set documentId in metadata as well
1388
+ customMetadata: metadata
1389
+ // Pass the custom metadata
1437
1390
  });
1438
1391
  const memoryWithScope = {
1439
1392
  ...documentMemory,
@@ -3060,7 +3013,8 @@ async function uploadKnowledgeHandler(req, res, runtime) {
3060
3013
  }
3061
3014
  const processingPromises = fileUrls.map(async (fileUrl) => {
3062
3015
  try {
3063
- const knowledgeId = createUniqueUuid3(runtime, fileUrl);
3016
+ const normalizedUrl = normalizeS3Url(fileUrl);
3017
+ const knowledgeId = createUniqueUuid3(runtime, normalizedUrl);
3064
3018
  const urlObject = new URL(fileUrl);
3065
3019
  const pathSegments = urlObject.pathname.split("/");
3066
3020
  const encodedFilename = pathSegments[pathSegments.length - 1] || "document.pdf";
@@ -3097,9 +3051,9 @@ async function uploadKnowledgeHandler(req, res, runtime) {
3097
3051
  worldId: runtime.agentId,
3098
3052
  roomId: runtime.agentId,
3099
3053
  entityId: runtime.agentId,
3100
- // Store the source URL in metadata
3054
+ // Store the normalized URL in metadata
3101
3055
  metadata: {
3102
- url: fileUrl
3056
+ url: normalizedUrl
3103
3057
  }
3104
3058
  };
3105
3059
  logger5.debug(`[KNOWLEDGE URL HANDLER] Processing knowledge from URL: ${fileUrl} (type: ${contentType})`);
@@ -3155,11 +3109,12 @@ async function getKnowledgeDocumentsHandler(req, res, runtime) {
3155
3109
  });
3156
3110
  let filteredMemories = memories;
3157
3111
  if (fileUrls && fileUrls.length > 0) {
3158
- const urlBasedIds = fileUrls.map((url) => createUniqueUuid3(runtime, url));
3112
+ const normalizedRequestUrls = fileUrls.map((url) => normalizeS3Url(url));
3113
+ const urlBasedIds = normalizedRequestUrls.map((url) => createUniqueUuid3(runtime, url));
3159
3114
  filteredMemories = memories.filter(
3160
3115
  (memory) => urlBasedIds.includes(memory.id) || // If the ID corresponds directly
3161
3116
  // Or if the URL is stored in the metadata (check if it exists)
3162
- memory.metadata && "url" in memory.metadata && typeof memory.metadata.url === "string" && fileUrls.includes(memory.metadata.url)
3117
+ memory.metadata && "url" in memory.metadata && typeof memory.metadata.url === "string" && normalizedRequestUrls.includes(normalizeS3Url(memory.metadata.url))
3163
3118
  );
3164
3119
  logger5.debug(`[KNOWLEDGE GET HANDLER] Filtered documents by URLs: ${fileUrls.length} URLs, found ${filteredMemories.length} matching documents`);
3165
3120
  }
@@ -3376,13 +3331,17 @@ async function getKnowledgeChunksHandler(req, res, runtime) {
3376
3331
  try {
3377
3332
  const limit = req.query.limit ? Number.parseInt(req.query.limit, 10) : 100;
3378
3333
  const before = req.query.before ? Number.parseInt(req.query.before, 10) : Date.now();
3334
+ const documentId = req.query.documentId;
3379
3335
  const chunks = await service.getMemories({
3380
3336
  tableName: "knowledge",
3381
3337
  // or whatever table stores the chunks
3382
3338
  count: limit,
3383
3339
  end: before
3384
3340
  });
3385
- sendSuccess(res, { chunks });
3341
+ const filteredChunks = documentId ? chunks.filter(
3342
+ (chunk) => chunk.metadata && typeof chunk.metadata === "object" && "documentId" in chunk.metadata && chunk.metadata.documentId === documentId
3343
+ ) : chunks;
3344
+ sendSuccess(res, { chunks: filteredChunks });
3386
3345
  } catch (error) {
3387
3346
  logger5.error("[KNOWLEDGE CHUNKS GET HANDLER] Error retrieving chunks:", error);
3388
3347
  sendError(res, 500, "RETRIEVAL_ERROR", "Failed to retrieve knowledge chunks", error.message);
@@ -3474,7 +3433,7 @@ var knowledgePlugin = {
3474
3433
  try {
3475
3434
  const service = runtime.getService(KnowledgeService.serviceType);
3476
3435
  if (service instanceof KnowledgeService) {
3477
- const { loadDocsFromPath: loadDocsFromPath2 } = await import("./docs-loader-2S6H7F4L.js");
3436
+ const { loadDocsFromPath: loadDocsFromPath2 } = await import("./docs-loader-NAE6ASGY.js");
3478
3437
  const result = await loadDocsFromPath2(service, runtime.agentId);
3479
3438
  if (result.successful > 0) {
3480
3439
  logger6.info(`Loaded ${result.successful} documents from docs folder on startup`);