feat(connectors): add support for Matrix (#82)
* feat(connectors): add support for Matrix Signed-off-by: mudler <mudler@localai.io> * make it functional Signed-off-by: mudler <mudler@localai.io> --------- Signed-off-by: mudler <mudler@localai.io>
This commit is contained in:
committed by
GitHub
parent
67cb5937e7
commit
087a5fbe0f
5
go.mod
5
go.mod
@@ -28,6 +28,7 @@ require (
|
|||||||
github.com/valyala/fasthttp v1.61.0
|
github.com/valyala/fasthttp v1.61.0
|
||||||
golang.org/x/crypto v0.37.0
|
golang.org/x/crypto v0.37.0
|
||||||
jaytaylor.com/html2text v0.0.0-20230321000545-74c2419ad056
|
jaytaylor.com/html2text v0.0.0-20230321000545-74c2419ad056
|
||||||
|
maunium.net/go/mautrix v0.17.0
|
||||||
mvdan.cc/xurls/v2 v2.6.0
|
mvdan.cc/xurls/v2 v2.6.0
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -79,6 +80,7 @@ require (
|
|||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
github.com/pkoukk/tiktoken-go v0.1.7 // indirect
|
github.com/pkoukk/tiktoken-go v0.1.7 // indirect
|
||||||
github.com/rivo/uniseg v0.4.7 // indirect
|
github.com/rivo/uniseg v0.4.7 // indirect
|
||||||
|
github.com/rs/zerolog v1.31.0 // indirect
|
||||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
|
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
|
||||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
||||||
github.com/temoto/robotstxt v1.1.2 // indirect
|
github.com/temoto/robotstxt v1.1.2 // indirect
|
||||||
@@ -90,9 +92,11 @@ require (
|
|||||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
|
||||||
|
go.mau.fi/util v0.3.0 // indirect
|
||||||
go.starlark.net v0.0.0-20250417143717-f57e51f710eb // indirect
|
go.starlark.net v0.0.0-20250417143717-f57e51f710eb // indirect
|
||||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||||
golang.org/x/arch v0.16.0 // indirect
|
golang.org/x/arch v0.16.0 // indirect
|
||||||
|
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect
|
||||||
golang.org/x/net v0.39.0 // indirect
|
golang.org/x/net v0.39.0 // indirect
|
||||||
golang.org/x/sys v0.32.0 // indirect
|
golang.org/x/sys v0.32.0 // indirect
|
||||||
golang.org/x/text v0.24.0 // indirect
|
golang.org/x/text v0.24.0 // indirect
|
||||||
@@ -100,4 +104,5 @@ require (
|
|||||||
google.golang.org/appengine v1.6.8 // indirect
|
google.golang.org/appengine v1.6.8 // indirect
|
||||||
google.golang.org/protobuf v1.36.6 // indirect
|
google.golang.org/protobuf v1.36.6 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
maunium.net/go/maulogger/v2 v2.4.1 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
17
go.sum
17
go.sum
@@ -27,6 +27,7 @@ github.com/chasefleming/elem-go v0.30.0/go.mod h1:hz73qILBIKnTgOujnSMtEj20/epI+f
|
|||||||
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
||||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||||
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/dave-gray101/v2keyauth v0.0.0-20240624150259-c45d584d25e2 h1:flLYmnQFZNo04x2NPehMbf30m7Pli57xwZ0NFqR/hb0=
|
github.com/dave-gray101/v2keyauth v0.0.0-20240624150259-c45d584d25e2 h1:flLYmnQFZNo04x2NPehMbf30m7Pli57xwZ0NFqR/hb0=
|
||||||
github.com/dave-gray101/v2keyauth v0.0.0-20240624150259-c45d584d25e2/go.mod h1:NtWqRzAp/1tw+twkW8uuBenEVVYndEAZACWU3F3xdoQ=
|
github.com/dave-gray101/v2keyauth v0.0.0-20240624150259-c45d584d25e2/go.mod h1:NtWqRzAp/1tw+twkW8uuBenEVVYndEAZACWU3F3xdoQ=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@@ -66,6 +67,7 @@ github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
|||||||
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/gocolly/colly v1.2.0 h1:qRz9YAn8FIH0qzgNUw+HT9UN7wm1oF9OBAilwEWpyrI=
|
github.com/gocolly/colly v1.2.0 h1:qRz9YAn8FIH0qzgNUw+HT9UN7wm1oF9OBAilwEWpyrI=
|
||||||
github.com/gocolly/colly v1.2.0/go.mod h1:Hof5T3ZswNVsOHYmba1u03W65HDWgpV5HifSuueE0EA=
|
github.com/gocolly/colly v1.2.0/go.mod h1:Hof5T3ZswNVsOHYmba1u03W65HDWgpV5HifSuueE0EA=
|
||||||
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI=
|
github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI=
|
||||||
github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||||
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
|
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
|
||||||
@@ -119,8 +121,11 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
|||||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||||
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
||||||
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
||||||
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
@@ -156,6 +161,9 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
|||||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||||
github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a h1:w3tdWGKbLGBPtR/8/oO74W6hmz0qE5q0z9aqSAewaaM=
|
github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a h1:w3tdWGKbLGBPtR/8/oO74W6hmz0qE5q0z9aqSAewaaM=
|
||||||
github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a/go.mod h1:S8kfXMp+yh77OxPD4fdM6YUknrZpQxLhvxzS4gDHENY=
|
github.com/rogpeppe/go-internal v1.13.2-0.20241226121412-a5dc8ff20d0a/go.mod h1:S8kfXMp+yh77OxPD4fdM6YUknrZpQxLhvxzS4gDHENY=
|
||||||
|
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
|
github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A=
|
||||||
|
github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
|
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
|
||||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||||
github.com/sashabaranov/go-openai v1.38.3 h1:cpDHJKH3WOuCx7QOsux4umjMPNZCUJrXW0FkXotjM4Q=
|
github.com/sashabaranov/go-openai v1.38.3 h1:cpDHJKH3WOuCx7QOsux4umjMPNZCUJrXW0FkXotjM4Q=
|
||||||
@@ -206,6 +214,8 @@ github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+x
|
|||||||
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
go.mau.fi/util v0.3.0 h1:Lt3lbRXP6ZBqTINK0EieRWor3zEwwwrDT14Z5N8RUCs=
|
||||||
|
go.mau.fi/util v0.3.0/go.mod h1:9dGsBCCbZJstx16YgnVMVi3O2bOizELoKpugLD4FoGs=
|
||||||
go.starlark.net v0.0.0-20250417143717-f57e51f710eb h1:zOg9DxxrorEmgGUr5UPdCEwKqiqG0MlZciuCuA3XiDE=
|
go.starlark.net v0.0.0-20250417143717-f57e51f710eb h1:zOg9DxxrorEmgGUr5UPdCEwKqiqG0MlZciuCuA3XiDE=
|
||||||
go.starlark.net v0.0.0-20250417143717-f57e51f710eb/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8=
|
go.starlark.net v0.0.0-20250417143717-f57e51f710eb/go.mod h1:YKMCv9b1WrfWmeqdV5MAuEHWsu5iC+fe6kYl2sQjdI8=
|
||||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||||
@@ -221,6 +231,8 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v
|
|||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||||
|
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o=
|
||||||
|
golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
@@ -251,6 +263,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
@@ -310,6 +323,10 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
jaytaylor.com/html2text v0.0.0-20230321000545-74c2419ad056 h1:6YFJoB+0fUH6X3xU/G2tQqCYg+PkGtnZ5nMR5rpw72g=
|
jaytaylor.com/html2text v0.0.0-20230321000545-74c2419ad056 h1:6YFJoB+0fUH6X3xU/G2tQqCYg+PkGtnZ5nMR5rpw72g=
|
||||||
jaytaylor.com/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:OxvTsCwKosqQ1q7B+8FwXqg4rKZ/UG9dUW+g/VL2xH4=
|
jaytaylor.com/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:OxvTsCwKosqQ1q7B+8FwXqg4rKZ/UG9dUW+g/VL2xH4=
|
||||||
|
maunium.net/go/maulogger/v2 v2.4.1 h1:N7zSdd0mZkB2m2JtFUsiGTQQAdP0YeFWT7YMc80yAL8=
|
||||||
|
maunium.net/go/maulogger/v2 v2.4.1/go.mod h1:omPuYwYBILeVQobz8uO3XC8DIRuEb5rXYlQSuqrbCho=
|
||||||
|
maunium.net/go/mautrix v0.17.0 h1:scc1qlUbzPn+wc+3eAPquyD+3gZwwy/hBANBm+iGKK8=
|
||||||
|
maunium.net/go/mautrix v0.17.0/go.mod h1:j+puTEQCEydlVxhJ/dQP5chfa26TdvBO7X6F3Ataav8=
|
||||||
mvdan.cc/xurls/v2 v2.6.0 h1:3NTZpeTxYVWNSokW3MKeyVkz/j7uYXYiMtXRUfmjbgI=
|
mvdan.cc/xurls/v2 v2.6.0 h1:3NTZpeTxYVWNSokW3MKeyVkz/j7uYXYiMtXRUfmjbgI=
|
||||||
mvdan.cc/xurls/v2 v2.6.0/go.mod h1:bCvEZ1XvdA6wDnxY7jPPjEmigDtvtvPXAD/Exa9IMSk=
|
mvdan.cc/xurls/v2 v2.6.0/go.mod h1:bCvEZ1XvdA6wDnxY7jPPjEmigDtvtvPXAD/Exa9IMSk=
|
||||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ const (
|
|||||||
ConnectorGithubIssues = "github-issues"
|
ConnectorGithubIssues = "github-issues"
|
||||||
ConnectorGithubPRs = "github-prs"
|
ConnectorGithubPRs = "github-prs"
|
||||||
ConnectorTwitter = "twitter"
|
ConnectorTwitter = "twitter"
|
||||||
|
ConnectorMatrix = "matrix"
|
||||||
)
|
)
|
||||||
|
|
||||||
var AvailableConnectors = []string{
|
var AvailableConnectors = []string{
|
||||||
@@ -29,6 +30,7 @@ var AvailableConnectors = []string{
|
|||||||
ConnectorGithubIssues,
|
ConnectorGithubIssues,
|
||||||
ConnectorGithubPRs,
|
ConnectorGithubPRs,
|
||||||
ConnectorTwitter,
|
ConnectorTwitter,
|
||||||
|
ConnectorMatrix,
|
||||||
}
|
}
|
||||||
|
|
||||||
func Connectors(a *state.AgentConfig) []state.Connector {
|
func Connectors(a *state.AgentConfig) []state.Connector {
|
||||||
@@ -66,6 +68,8 @@ func Connectors(a *state.AgentConfig) []state.Connector {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
conns = append(conns, cc)
|
conns = append(conns, cc)
|
||||||
|
case ConnectorMatrix:
|
||||||
|
conns = append(conns, connectors.NewMatrix(config))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return conns
|
return conns
|
||||||
@@ -108,5 +112,10 @@ func ConnectorsConfigMeta() []config.FieldGroup {
|
|||||||
Label: "Twitter",
|
Label: "Twitter",
|
||||||
Fields: connectors.TwitterConfigMeta(),
|
Fields: connectors.TwitterConfigMeta(),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "matrix",
|
||||||
|
Label: "Matrix",
|
||||||
|
Fields: connectors.MatrixConfigMeta(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
317
services/connectors/matrix.go
Normal file
317
services/connectors/matrix.go
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
package connectors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/mudler/LocalAGI/core/agent"
|
||||||
|
"github.com/mudler/LocalAGI/core/types"
|
||||||
|
"github.com/mudler/LocalAGI/pkg/config"
|
||||||
|
"github.com/mudler/LocalAGI/pkg/xlog"
|
||||||
|
"github.com/sashabaranov/go-openai"
|
||||||
|
"maunium.net/go/mautrix"
|
||||||
|
"maunium.net/go/mautrix/event"
|
||||||
|
"maunium.net/go/mautrix/id"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Matrix struct {
|
||||||
|
homeserverURL string
|
||||||
|
userID string
|
||||||
|
accessToken string
|
||||||
|
roomID string
|
||||||
|
roomMode bool
|
||||||
|
|
||||||
|
// To track placeholder messages
|
||||||
|
placeholders map[string]string // map[jobUUID]messageID
|
||||||
|
placeholderMutex sync.RWMutex
|
||||||
|
client *mautrix.Client
|
||||||
|
|
||||||
|
// Track active jobs for cancellation
|
||||||
|
activeJobs map[string][]*types.Job // map[roomID]bool to track if a room has active processing
|
||||||
|
activeJobsMutex sync.RWMutex
|
||||||
|
|
||||||
|
conversationTracker *ConversationTracker[string]
|
||||||
|
}
|
||||||
|
|
||||||
|
const matrixThinkingMessage = "🤔 thinking..."
|
||||||
|
|
||||||
|
func NewMatrix(config map[string]string) *Matrix {
|
||||||
|
duration, err := time.ParseDuration(config["lastMessageDuration"])
|
||||||
|
if err != nil {
|
||||||
|
duration = 5 * time.Minute
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Matrix{
|
||||||
|
homeserverURL: config["homeserverURL"],
|
||||||
|
userID: config["userID"],
|
||||||
|
accessToken: config["accessToken"],
|
||||||
|
roomID: config["roomID"],
|
||||||
|
roomMode: config["roomMode"] == "true",
|
||||||
|
conversationTracker: NewConversationTracker[string](duration),
|
||||||
|
placeholders: make(map[string]string),
|
||||||
|
activeJobs: make(map[string][]*types.Job),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Matrix) AgentResultCallback() func(state types.ActionState) {
|
||||||
|
return func(state types.ActionState) {
|
||||||
|
// Mark the job as completed when we get the final result
|
||||||
|
if state.ActionCurrentState.Job != nil && state.ActionCurrentState.Job.Metadata != nil {
|
||||||
|
if room, ok := state.ActionCurrentState.Job.Metadata["room"].(string); ok && room != "" {
|
||||||
|
m.activeJobsMutex.Lock()
|
||||||
|
delete(m.activeJobs, room)
|
||||||
|
m.activeJobsMutex.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Matrix) AgentReasoningCallback() func(state types.ActionCurrentState) bool {
|
||||||
|
return func(state types.ActionCurrentState) bool {
|
||||||
|
// Check if we have a placeholder message for this job
|
||||||
|
m.placeholderMutex.RLock()
|
||||||
|
msgID, exists := m.placeholders[state.Job.UUID]
|
||||||
|
room := ""
|
||||||
|
if state.Job.Metadata != nil {
|
||||||
|
if r, ok := state.Job.Metadata["room"].(string); ok {
|
||||||
|
room = r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.placeholderMutex.RUnlock()
|
||||||
|
|
||||||
|
if !exists || msgID == "" || room == "" || m.client == nil {
|
||||||
|
return true // Skip if we don't have a message to update
|
||||||
|
}
|
||||||
|
|
||||||
|
thought := matrixThinkingMessage + "\n\n"
|
||||||
|
if state.Reasoning != "" {
|
||||||
|
thought += "Current thought process:\n" + state.Reasoning
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the placeholder message with the current reasoning
|
||||||
|
_, err := m.client.SendText(context.Background(), id.RoomID(room), thought)
|
||||||
|
if err != nil {
|
||||||
|
xlog.Error(fmt.Sprintf("Error updating reasoning message: %v", err))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cancelActiveJobForRoom cancels any active job for the given room
|
||||||
|
func (m *Matrix) cancelActiveJobForRoom(roomID string) {
|
||||||
|
m.activeJobsMutex.RLock()
|
||||||
|
ctxs, exists := m.activeJobs[roomID]
|
||||||
|
m.activeJobsMutex.RUnlock()
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
xlog.Info(fmt.Sprintf("Cancelling active job for room: %s", roomID))
|
||||||
|
|
||||||
|
// Mark the job as inactive
|
||||||
|
m.activeJobsMutex.Lock()
|
||||||
|
for _, c := range ctxs {
|
||||||
|
c.Cancel()
|
||||||
|
}
|
||||||
|
delete(m.activeJobs, roomID)
|
||||||
|
m.activeJobsMutex.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Matrix) handleRoomMessage(a *agent.Agent, evt *event.Event) {
|
||||||
|
if m.roomID != evt.RoomID.String() && m.roomMode { // If we have a roomID and it's not the same as the event room
|
||||||
|
// Skip messages from other rooms
|
||||||
|
xlog.Info("Skipping reply to room", evt.RoomID, m.roomID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if evt.Sender == id.UserID(m.userID) {
|
||||||
|
// Skip messages from ourselves
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip if message does not mention the bot
|
||||||
|
mentioned := false
|
||||||
|
if evt.Content.AsMessage().Mentions != nil {
|
||||||
|
for _, mention := range evt.Content.AsMessage().Mentions.UserIDs {
|
||||||
|
if mention == m.client.UserID {
|
||||||
|
mentioned = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !mentioned && !m.roomMode {
|
||||||
|
xlog.Info("Skipping reply because it does not mention the bot", evt.RoomID, m.roomID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel any active job for this room before starting a new one
|
||||||
|
m.cancelActiveJobForRoom(evt.RoomID.String())
|
||||||
|
|
||||||
|
currentConv := m.conversationTracker.GetConversation(evt.RoomID.String())
|
||||||
|
|
||||||
|
message := evt.Content.AsMessage().Body
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
agentOptions := []types.JobOption{
|
||||||
|
types.WithUUID(evt.ID.String()),
|
||||||
|
}
|
||||||
|
|
||||||
|
currentConv = append(currentConv, openai.ChatCompletionMessage{
|
||||||
|
Role: "user",
|
||||||
|
Content: message,
|
||||||
|
})
|
||||||
|
|
||||||
|
m.conversationTracker.AddMessage(
|
||||||
|
evt.RoomID.String(), currentConv[len(currentConv)-1],
|
||||||
|
)
|
||||||
|
|
||||||
|
agentOptions = append(agentOptions, types.WithConversationHistory(currentConv))
|
||||||
|
|
||||||
|
// Add room to metadata for tracking
|
||||||
|
metadata := map[string]interface{}{
|
||||||
|
"room": evt.RoomID.String(),
|
||||||
|
}
|
||||||
|
agentOptions = append(agentOptions, types.WithMetadata(metadata))
|
||||||
|
|
||||||
|
job := types.NewJob(agentOptions...)
|
||||||
|
|
||||||
|
// Mark this room as having an active job
|
||||||
|
m.activeJobsMutex.Lock()
|
||||||
|
m.activeJobs[evt.RoomID.String()] = append(m.activeJobs[evt.RoomID.String()], job)
|
||||||
|
m.activeJobsMutex.Unlock()
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
// Mark job as complete
|
||||||
|
m.activeJobsMutex.Lock()
|
||||||
|
job.Cancel()
|
||||||
|
for i, j := range m.activeJobs[evt.RoomID.String()] {
|
||||||
|
if j.UUID == job.UUID {
|
||||||
|
m.activeJobs[evt.RoomID.String()] = append(m.activeJobs[evt.RoomID.String()][:i], m.activeJobs[evt.RoomID.String()][i+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.activeJobsMutex.Unlock()
|
||||||
|
}()
|
||||||
|
|
||||||
|
res := a.Ask(
|
||||||
|
agentOptions...,
|
||||||
|
)
|
||||||
|
|
||||||
|
if res.Response == "" {
|
||||||
|
xlog.Debug(fmt.Sprintf("Empty response from agent"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if res.Error != nil {
|
||||||
|
xlog.Error(fmt.Sprintf("Error from agent: %v", res.Error))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
m.conversationTracker.AddMessage(
|
||||||
|
evt.RoomID.String(), openai.ChatCompletionMessage{
|
||||||
|
Role: "assistant",
|
||||||
|
Content: res.Response,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
// Send the response to the room
|
||||||
|
_, err := m.client.SendText(context.Background(), evt.RoomID, res.Response)
|
||||||
|
if err != nil {
|
||||||
|
xlog.Error(fmt.Sprintf("Error sending message: %v", err))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Matrix) Start(a *agent.Agent) {
|
||||||
|
// Create Matrix client
|
||||||
|
client, err := mautrix.NewClient(m.homeserverURL, id.UserID(m.userID), m.accessToken)
|
||||||
|
if err != nil {
|
||||||
|
xlog.Error(fmt.Sprintf("Error creating Matrix client: %v", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
xlog.Info("Matrix client created")
|
||||||
|
m.client = client
|
||||||
|
|
||||||
|
// Set up event handler
|
||||||
|
syncer := client.Syncer.(*mautrix.DefaultSyncer)
|
||||||
|
syncer.OnEventType(event.EventMessage, func(ctx context.Context, evt *event.Event) {
|
||||||
|
xlog.Info("Received message", evt.Content.AsMessage().Body)
|
||||||
|
m.handleRoomMessage(a, evt)
|
||||||
|
})
|
||||||
|
|
||||||
|
syncer.OnEventType(event.StateMember, func(ctx context.Context, evt *event.Event) {
|
||||||
|
if evt.GetStateKey() == client.UserID.String() && evt.Content.AsMember().Membership == event.MembershipInvite {
|
||||||
|
_, err := client.JoinRoomByID(ctx, evt.RoomID)
|
||||||
|
if err != nil {
|
||||||
|
xlog.Error(fmt.Sprintf("Error joining room: %v", err))
|
||||||
|
}
|
||||||
|
xlog.Info(fmt.Sprintf("Joined room: %s (%s)", evt.RoomID.String(), evt.RoomID.URI()))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
syncer.OnEventType(event.EventEncrypted, func(ctx context.Context, evt *event.Event) {
|
||||||
|
xlog.Info("Received encrypted message, this does not work yet", evt.RoomID.String())
|
||||||
|
//m.handleRoomMessage(a, evt)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Start syncing
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
err := client.SyncWithContext(a.Context())
|
||||||
|
|
||||||
|
xlog.Info("Syncing")
|
||||||
|
if err != nil {
|
||||||
|
xlog.Error(fmt.Sprintf("Error syncing: %v", err))
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Handle shutdown
|
||||||
|
go func() {
|
||||||
|
<-a.Context().Done()
|
||||||
|
client.StopSync()
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MatrixConfigMeta returns the metadata for Matrix connector configuration fields
|
||||||
|
func MatrixConfigMeta() []config.Field {
|
||||||
|
return []config.Field{
|
||||||
|
{
|
||||||
|
Name: "homeserverURL",
|
||||||
|
Label: "Homeserver URL",
|
||||||
|
Type: config.FieldTypeText,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "userID",
|
||||||
|
Label: "User ID",
|
||||||
|
Type: config.FieldTypeText,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "accessToken",
|
||||||
|
Label: "Access Token",
|
||||||
|
Type: config.FieldTypeText,
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "roomID",
|
||||||
|
Label: "Room ID",
|
||||||
|
Type: config.FieldTypeText,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "roomMode",
|
||||||
|
Label: "Room Mode",
|
||||||
|
Type: config.FieldTypeCheckbox,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "lastMessageDuration",
|
||||||
|
Label: "Last Message Duration",
|
||||||
|
Type: config.FieldTypeText,
|
||||||
|
DefaultValue: "5m",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user