From 99173ed216bd537dc650a6f1ce3c9295ce123e66 Mon Sep 17 00:00:00 2001 From: Megumin Date: Mon, 14 Apr 2025 19:58:52 +0800 Subject: [PATCH] feat: manus agent --- flow/agent/manus/README.md | 6 + flow/agent/manus/assets/img.png | Bin 0 -> 34869 bytes flow/agent/manus/go.mod | 80 ++++++ flow/agent/manus/go.sum | 313 +++++++++++++++++++++ flow/agent/manus/log.go | 94 +++++++ flow/agent/manus/manus.go | 473 ++++++++++++++++++++++++++++++++ flow/agent/manus/prompt.go | 48 ++++ go.mod | 2 +- go.sum | 4 +- 9 files changed, 1017 insertions(+), 3 deletions(-) create mode 100644 flow/agent/manus/README.md create mode 100644 flow/agent/manus/assets/img.png create mode 100644 flow/agent/manus/go.mod create mode 100644 flow/agent/manus/go.sum create mode 100644 flow/agent/manus/log.go create mode 100644 flow/agent/manus/manus.go create mode 100644 flow/agent/manus/prompt.go diff --git a/flow/agent/manus/README.md b/flow/agent/manus/README.md new file mode 100644 index 0000000..b82e44b --- /dev/null +++ b/flow/agent/manus/README.md @@ -0,0 +1,6 @@ +This project implements a simple manus agent using the Eino framework, inspired by the excellent work of the [OpenManus](https://github.com/mannaandpoem/OpenManus). + + + +agent structure: +![img.png](assets/img.png) \ No newline at end of file diff --git a/flow/agent/manus/assets/img.png b/flow/agent/manus/assets/img.png new file mode 100644 index 0000000000000000000000000000000000000000..4db90eefc6cddbc1b6cd08caef6b0dec6d2c2e47 GIT binary patch literal 34869 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 SMhD{meF|5VFO+>A`2PU{$yIm& literal 0 HcmV?d00001 diff --git a/flow/agent/manus/go.mod b/flow/agent/manus/go.mod new file mode 100644 index 0000000..d03885e --- /dev/null +++ b/flow/agent/manus/go.mod @@ -0,0 +1,80 @@ +module github.com/cloudwego/eino-examples/flow/agent/manus + +go 1.24 + +toolchain go1.24.1 + +require ( + github.com/cloudwego/eino v0.3.23 + github.com/cloudwego/eino-ext/callbacks/langfuse v0.0.0-20250415073426-726b929afbc2 + github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250421080917-56d9b5a9ae10 + github.com/cloudwego/eino-ext/components/tool/browseruse v0.0.0-20250421090053-2091919102c7 + github.com/cloudwego/eino-ext/components/tool/commandline v0.0.0-20250421090053-2091919102c7 + github.com/cloudwego/eino-ext/components/tool/duckduckgo v0.0.0-20250416093724-5f53a5d6cc28 + github.com/google/uuid v1.6.0 +) + +require ( + github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect + github.com/Microsoft/go-winio v0.4.14 // indirect + github.com/bytedance/sonic v1.13.2 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/chromedp/cdproto v0.0.0-20250319231242-a755498943c8 // indirect + github.com/chromedp/chromedp v0.13.3 // indirect + github.com/chromedp/sysutil v1.1.0 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect + github.com/cloudwego/eino-ext/libs/acl/langfuse v0.0.0-20250415073426-726b929afbc2 // indirect + github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250416093724-5f53a5d6cc28 // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/docker v28.0.4+incompatible // indirect + github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-units v0.5.0 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect + github.com/getkin/kin-openapi v0.118.0 // indirect + github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/swag v0.19.5 // indirect + github.com/gobwas/httphead v0.1.0 // indirect + github.com/gobwas/pool v0.2.1 // indirect + github.com/gobwas/ws v1.4.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/goph/emperror v0.17.2 // indirect + github.com/invopop/yaml v0.1.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/meguminnnnnnnnn/go-openai v0.0.0-20250408071642-761325becfd6 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/nikolalohinski/gonja v1.5.3 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect + github.com/pelletier/go-toml/v2 v2.0.9 // indirect + github.com/perimeterx/marshmallow v1.1.4 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/yargevad/filepathx v1.0.0 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect + go.opentelemetry.io/proto/otlp v1.5.0 // indirect + golang.org/x/arch v0.12.0 // indirect + golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect + golang.org/x/sys v0.31.0 // indirect + google.golang.org/grpc v1.71.1 // indirect + google.golang.org/protobuf v1.36.6 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/flow/agent/manus/go.sum b/flow/agent/manus/go.sum new file mode 100644 index 0000000..cab3877 --- /dev/null +++ b/flow/agent/manus/go.sum @@ -0,0 +1,313 @@ +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/airbrake/gobrake v3.6.1+incompatible/go.mod h1:wM4gu3Cn0W0K7GUuVWnlXZU11AGBXMILnrdOU8Kn00o= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/bugsnag/bugsnag-go v1.4.0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/panicwrap v1.2.0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/bytedance/mockey v1.2.14 h1:KZaFgPdiUwW+jOWFieo3Lr7INM1P+6adO3hxZhDswY8= +github.com/bytedance/mockey v1.2.14/go.mod h1:1BPHF9sol5R1ud/+0VEHGQq/+i2lN+GTsr3O2Q9IENY= +github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ= +github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/certifi/gocertifi v0.0.0-20190105021004-abcd57078448/go.mod h1:GJKEexRPVJrBSOjoqN5VNOIKJ5Q3RViH6eu3puDRwx4= +github.com/chromedp/cdproto v0.0.0-20250319231242-a755498943c8 h1:AqW2bDQf67Zbq6Tpop/+yJSIknxhiQecO2B8jNYTAPs= +github.com/chromedp/cdproto v0.0.0-20250319231242-a755498943c8/go.mod h1:NItd7aLkcfOA/dcMXvl8p1u+lQqioRMq/SqDp71Pb/k= +github.com/chromedp/chromedp v0.13.3 h1:c6nTn97XQBykzcXiGYL5LLebw3h3CEyrCihm4HquYh0= +github.com/chromedp/chromedp v0.13.3/go.mod h1:khsDP9OP20GrowpJfZ7N05iGCwcAYxk7qf9AZBzR3Qw= +github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM= +github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/eino v0.3.23 h1:fPjskHM85I4PPa+GZPoh76bMCbdRKWVKd52gdvcGHt8= +github.com/cloudwego/eino v0.3.23/go.mod h1:wUjz990apdsaOraOXdh6CdhVXq8DJsOvLsVlxNTcNfY= +github.com/cloudwego/eino-ext/callbacks/langfuse v0.0.0-20250415073426-726b929afbc2 h1:M/u7nNq1dXEKlwjy2CMUefO/lFk5zBPbm/r2G70TXGc= +github.com/cloudwego/eino-ext/callbacks/langfuse v0.0.0-20250415073426-726b929afbc2/go.mod h1:XWVF6RYWD1O7Ax/Mq5S3NZbdmHkIuYws7PvM92Q+ZJQ= +github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250421080917-56d9b5a9ae10 h1:WHS+FTfEoOy+hzams6I3uud2nyHO54GS0sIZSry9pdc= +github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250421080917-56d9b5a9ae10/go.mod h1:8gMakAGQUR+IaWTSD0cpcD4U5FYq5puZ73/QjXqs1oU= +github.com/cloudwego/eino-ext/components/tool/browseruse v0.0.0-20250421090053-2091919102c7 h1:Bp/Cf51YzUg0wsJuGwerCVrs0yB/306FPkmVQD1cSMg= +github.com/cloudwego/eino-ext/components/tool/browseruse v0.0.0-20250421090053-2091919102c7/go.mod h1:OGk7Ejiwuciw9TrzxaaXT3My2+bdTIFE9xk/AlG0ZK0= +github.com/cloudwego/eino-ext/components/tool/commandline v0.0.0-20250421090053-2091919102c7 h1:lQtjLrApL4tKz1dQuYHxtfUv04O96UTAyPvkUlT608E= +github.com/cloudwego/eino-ext/components/tool/commandline v0.0.0-20250421090053-2091919102c7/go.mod h1:N6bMdRYu9ecKNWOGLJ/VZf5LEmpnM/1wrvrCmF+Ukio= +github.com/cloudwego/eino-ext/components/tool/duckduckgo v0.0.0-20250416093724-5f53a5d6cc28 h1:wtBt5XSf3LDa3dK63FTNaiU50+B58gO18St78Q91gjM= +github.com/cloudwego/eino-ext/components/tool/duckduckgo v0.0.0-20250416093724-5f53a5d6cc28/go.mod h1:bLd1hxvmOxU0KZOl0Cd73CCku9gGSwx+DyX0nG7RJj0= +github.com/cloudwego/eino-ext/libs/acl/langfuse v0.0.0-20250415073426-726b929afbc2 h1:QJ4OxgSa/Z0Z3PfX3uWG9NbHsYCoQwagZUkJwT2k1ZE= +github.com/cloudwego/eino-ext/libs/acl/langfuse v0.0.0-20250415073426-726b929afbc2/go.mod h1:nH8n+e6KG3w1cPMS1qT35Hxw19WJlYyWdWTQWnwJPFk= +github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250416093724-5f53a5d6cc28 h1:LZyLFdPglF5Obxc0KJoHc54Q5qqylcZFoWZrEfwxsqg= +github.com/cloudwego/eino-ext/libs/acl/openai v0.0.0-20250416093724-5f53a5d6cc28/go.mod h1:Ye0YAqpESCxMlnALNrjeNJjhS9q2PIdxVdJbtFeni8o= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v28.0.4+incompatible h1:JNNkBctYKurkw6FrHfKqY0nKIDf5nrbxjVBtS+cdcok= +github.com/docker/docker v28.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= +github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/getkin/kin-openapi v0.118.0 h1:z43njxPmJ7TaPpMSCQb7PN0dEYno4tyBPQcrFdHoLuM= +github.com/getkin/kin-openapi v0.118.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc= +github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 h1:F8d1AJ6M9UQCavhwmO6ZsrYLfG8zVFWfEfMS2MXPkSY= +github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs= +github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/goph/emperror v0.17.2 h1:yLapQcmEsO0ipe9p5TaN22djm3OFV/TfM/fcYP0/J18= +github.com/goph/emperror v0.17.2/go.mod h1:+ZbQ+fUNO/6FNiUo0ujtMjhgad9Xa6fQL9KhH4LNHic= +github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= +github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc= +github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= +github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= +github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/meguminnnnnnnnn/go-openai v0.0.0-20250408071642-761325becfd6 h1:nmdXxiUX48DZ2ELC/jSYzyGUVgxVEF2QJRGhLJ933zA= +github.com/meguminnnnnnnnn/go-openai v0.0.0-20250408071642-761325becfd6/go.mod h1:kyz7fcXqXtccmRAIARn1Q+cKLNXJHC3AoqqJGeCqNI0= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= +github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/nikolalohinski/gonja v1.5.3 h1:GsA+EEaZDZPGJ8JtpeGN78jidhOlxeJROpqMT9fTj9c= +github.com/nikolalohinski/gonja v1.5.3/go.mod h1:RmjwxNiXAEqcq1HeK5SSMmqFJvKOfTfXhkJv6YBtPa4= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw= +github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0= +github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0= +github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw= +github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rollbar/rollbar-go v1.0.2/go.mod h1:AcFs5f0I+c71bpHlXNNDbOWJiKwjFDtISeXco0L5PKQ= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f h1:Z2cODYsUxQPofhpYRMQVwWz4yUVpHF+vPi+eUdruUYI= +github.com/slongfield/pyfmt v0.0.0-20220222012616-ea85ff4c361f/go.mod h1:JqzWyvTuI2X4+9wOHmKSQCYxybB/8j6Ko43qVmXDuZg= +github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= +github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= +github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= +github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJzfthRT6usrui8uGmg= +github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/yargevad/filepathx v1.0.0 h1:SYcT+N3tYGi+NvazubCNlvgIPbzAk7i7y2dwg3I5FYc= +github.com/yargevad/filepathx v1.0.0/go.mod h1:BprfX/gpYNJHJfc35GjRRpVcwWXS89gGulUIU5tK3tA= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0fikVry1IsiUnXjf7QFvoNN3Xw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= +go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= +go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= +go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +golang.org/x/arch v0.12.0 h1:UsYJhbzPYGsT0HbEdmYcqtCv8UNGvnaL561NnIUvaKg= +golang.org/x/arch v0.12.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24= +google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/flow/agent/manus/log.go b/flow/agent/manus/log.go new file mode 100644 index 0000000..d69828f --- /dev/null +++ b/flow/agent/manus/log.go @@ -0,0 +1,94 @@ +/* + * Copyright 2024 CloudWeGo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "context" + "fmt" + "strings" + + "github.com/cloudwego/eino/callbacks" + "github.com/cloudwego/eino/components" + "github.com/cloudwego/eino/components/model" + "github.com/cloudwego/eino/components/tool" + "github.com/cloudwego/eino/schema" +) + +func newLogHandler() callbacks.Handler { + builder := callbacks.NewHandlerBuilder() + builder. + OnStartFn(func(ctx context.Context, info *callbacks.RunInfo, input callbacks.CallbackInput) context.Context { + if info.Component == components.ComponentOfTool { + tci := tool.ConvCallbackInput(input) + fmt.Printf("\033[32m[callback]: start [%s:%s:%s] input: %v\033[0m\n", info.Component, info.Type, info.Name, tci.ArgumentsInJSON) + } else { + fmt.Printf("\033[32m[callback]: start [%s:%s:%s]running...\033[0m\n", info.Component, info.Type, info.Name) + } + return ctx + }). + OnEndFn(func(ctx context.Context, info *callbacks.RunInfo, output callbacks.CallbackOutput) context.Context { + if info.Component == components.ComponentOfTool { + tco := tool.ConvCallbackOutput(output) + fmt.Printf("\033[32m[callback]: end [%s:%s:%s] result: %v\033[0m\n", info.Component, info.Type, info.Name, tco.Response) + } else if info.Component == components.ComponentOfChatModel { + cco := model.ConvCallbackOutput(output) + fmt.Printf("\033[32m[callback]: end [%s:%s:%s] output: %s\033[0m\n", info.Component, info.Type, info.Name, printMessage(cco.Message)) + } else { + fmt.Printf("\033[32m[callback]: end [%s:%s:%s]\033[0m\n", info.Component, info.Type, info.Name) + } + return ctx + }). + OnStartWithStreamInputFn(func(ctx context.Context, info *callbacks.RunInfo, input *schema.StreamReader[callbacks.CallbackInput]) context.Context { + input.Close() + fmt.Printf("\033[32m[callback]: start stream input [%s:%s:%s]running...\033[0m\n", info.Component, info.Type, info.Name) + return ctx + }). + OnEndWithStreamOutputFn(func(ctx context.Context, info *callbacks.RunInfo, output *schema.StreamReader[callbacks.CallbackOutput]) context.Context { + output.Close() + fmt.Printf("\033[32m[callback]: end stream output [%s:%s:%s]\033[0m\n", info.Component, info.Type, info.Name) + return ctx + }). + OnErrorFn(func(ctx context.Context, info *callbacks.RunInfo, err error) context.Context { + fmt.Printf("\033[31m[callback]: error [%s:%s:%s] - %v\033[0m\n", info.Component, info.Type, info.Name, err) + return ctx + }) + return builder.Build() +} + +func printMessage(m *schema.Message) string { + sb := strings.Builder{} + sb.WriteString("[") + sb.WriteString(string(m.Role)) + sb.WriteString("]") + if len(m.Content) > 0 { + sb.WriteString("Content: \"") + sb.WriteString(m.Content) + sb.WriteString("\" ") + } + if len(m.ToolCalls) > 0 { + sb.WriteString("ToolCalls: [") + for _, toolCall := range m.ToolCalls { + sb.WriteString("{Name: ") + sb.WriteString(toolCall.Function.Name) + sb.WriteString(", Arguments: ") + sb.WriteString(toolCall.Function.Arguments) + sb.WriteString("}") + } + sb.WriteString("]") + } + return sb.String() +} diff --git a/flow/agent/manus/manus.go b/flow/agent/manus/manus.go new file mode 100644 index 0000000..eb84aa5 --- /dev/null +++ b/flow/agent/manus/manus.go @@ -0,0 +1,473 @@ +/* + * Copyright 2024 CloudWeGo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "bufio" + "context" + "fmt" + "log" + "os" + "strings" + "time" + + "github.com/cloudwego/eino-ext/callbacks/langfuse" + "github.com/cloudwego/eino-ext/components/model/openai" + "github.com/cloudwego/eino-ext/components/tool/browseruse" + "github.com/cloudwego/eino-ext/components/tool/commandline" + "github.com/cloudwego/eino-ext/components/tool/commandline/sandbox" + "github.com/cloudwego/eino-ext/components/tool/duckduckgo/ddgsearch" + "github.com/cloudwego/eino/callbacks" + "github.com/cloudwego/eino/components/model" + "github.com/cloudwego/eino/components/tool" + "github.com/cloudwego/eino/compose" + "github.com/cloudwego/eino/schema" + "github.com/google/uuid" +) + +var ( + langfuseHost string + langfusePublicKey string + langfuseSecretKey string + + openaiAPIKey string + openaiModel string + openaiBaseURL string + + input string +) + +func init() { + langfuseHost = os.Getenv("LANGFUSE_HOST") + langfusePublicKey = os.Getenv("LANGFUSE_PUBLIC_KEY") + langfuseSecretKey = os.Getenv("LANGFUSE_SECRET_KEY") + + openaiAPIKey = os.Getenv("OPENAI_API_KEY") + openaiModel = os.Getenv("OPENAI_MODEL") + openaiBaseURL = os.Getenv("OPENAI_BASE_URL") + + input = "what is eino?" +} + +func main() { + ctx := context.Background() + + // init tools + sb := newSandbox(ctx) + defer sb.Cleanup(ctx) + commandlineTools := newCommandLineTools(ctx, sb) + browserTool := newBrowserTool(ctx) + defer browserTool.Cleanup() + + // init chat model + cm := newChatModel(ctx) + cm = bindTools(ctx, cm, append(commandlineTools, browserTool)) + + // init and register callback handlers for logging and tracing + var handlers []callbacks.Handler + if len(langfuseHost) > 0 { + langfuseHandler, flusher := newLangfuseHandler() + handlers = append(handlers, langfuseHandler) + defer flusher() + } + handlers = append(handlers, newLogHandler()) + callbacks.AppendGlobalHandlers(handlers...) + + // compose graph + agent := composeAgent(ctx, cm, browserTool, commandlineTools) + + // init langfuse trace + ctx = langfuse.SetTrace(ctx, langfuse.WithID(uuid.New().String())) + + var userInput string + for { + result, err := agent.Invoke(ctx, input, + compose.WithCheckPointID("1"), + compose.WithStateModifier(func(ctx context.Context, path compose.NodePath, s any) error { + s.(*state).UserInput = userInput + return nil + }), + compose.WithRuntimeMaxSteps(20), + ) + info, ok := compose.ExtractInterruptInfo(err) + if ok { + s := info.State.(*state) + fmt.Printf("ChatModel Output: %s\n", s.History[len(s.History)-1].Content) + fmt.Print("Do you want to continue? (y/n): ") + reader := bufio.NewReader(os.Stdin) + response, _ := reader.ReadString('\n') + response = strings.TrimSpace(response) + + if strings.ToLower(response) == "y" { + fmt.Print("Please enter your query: ") + userInput, _ = reader.ReadString('\n') + userInput = strings.TrimSpace(userInput) + } else { + userInput = "" + } + continue + } + if err != nil { + log.Printf("agent run error: %v", err) + return + } + fmt.Printf("[FinalResult]: %s", result) + break + } +} + +type state struct { + History []*schema.Message + UserInput string +} + +const ( + NodeKeyInputConvert = "InputConverter" + NodeKeyChatModel = "ChatModel" + NodeKeyToolsNode = "ToolsNode" + NodeKeyHuman = "Human" + NodeKeyOutputConvert = "OutputConverter" +) + +func composeAgent(ctx context.Context, + cm model.BaseChatModel, + browserTool *browseruse.Tool, + tools []tool.BaseTool, +) compose.Runnable[string, string] { + err := compose.RegisterSerializableType[state]("my state") + if err != nil { + log.Fatal(err) + } + err = compose.RegisterSerializableType[schema.ChatMessagePartType]("cmpt") + if err != nil { + log.Fatal(err) + } + err = compose.RegisterSerializableType[schema.ChatMessageImageURL]("cmiu") + if err != nil { + log.Fatal(err) + } + err = compose.RegisterSerializableType[schema.ChatMessageAudioURL]("cnau") + if err != nil { + log.Fatal(err) + } + err = compose.RegisterSerializableType[schema.ChatMessageVideoURL]("cmvu") + if err != nil { + log.Fatal(err) + } + err = compose.RegisterSerializableType[schema.ChatMessageFileURL]("cmfu") + if err != nil { + log.Fatal(err) + } + err = compose.RegisterSerializableType[schema.ImageURLDetail]("iud") + if err != nil { + log.Fatal(err) + } + + g := compose.NewGraph[string, string](compose.WithGenLocalState(func(ctx context.Context) *state { + return &state{History: []*schema.Message{}} + })) + + // register nodes + err = g.AddLambdaNode(NodeKeyInputConvert, compose.InvokableLambda(func(ctx context.Context, input string) (output []*schema.Message, err error) { + return []*schema.Message{ + schema.SystemMessage(systemPrompt), + schema.UserMessage(input), + }, nil + }), compose.WithNodeName(NodeKeyInputConvert)) + if err != nil { + log.Fatal(err) + } + + err = g.AddChatModelNode( + NodeKeyChatModel, + cm, + compose.WithNodeName(NodeKeyChatModel), + // append other node's output to History and load History to llm input + compose.WithStatePreHandler(func(ctx context.Context, in []*schema.Message, state *state) ([]*schema.Message, error) { + state.History = append(state.History, in...) + return state.History, nil + }), + compose.WithStatePostHandler(func(ctx context.Context, out *schema.Message, state *state) (*schema.Message, error) { + state.History = append(state.History, out) + return out, nil + }), + ) + if err != nil { + log.Fatal(err) + } + + toolsNode, err := compose.NewToolNode(ctx, &compose.ToolsNodeConfig{Tools: append(tools, browserTool)}) + if err != nil { + log.Fatal(err) + } + err = g.AddToolsNode( + NodeKeyToolsNode, + toolsNode, + compose.WithNodeName(NodeKeyToolsNode), + compose.WithStatePostHandler(appendNextPrompt(ctx, browserTool)), + ) + if err != nil { + log.Fatal(err) + } + + err = g.AddLambdaNode(NodeKeyHuman, compose.InvokableLambda(func(ctx context.Context, input *schema.Message) (output []*schema.Message, err error) { + return []*schema.Message{input}, nil + }), compose.WithNodeName(NodeKeyHuman), + compose.WithStatePostHandler(func(ctx context.Context, in []*schema.Message, state *state) ([]*schema.Message, error) { + if len(state.UserInput) > 0 { + return []*schema.Message{schema.UserMessage(state.UserInput)}, nil + } + return in, nil + })) + if err != nil { + log.Fatal(err) + } + + err = g.AddLambdaNode(NodeKeyOutputConvert, compose.InvokableLambda(func(ctx context.Context, input []*schema.Message) (output string, err error) { + return input[len(input)-1].Content, nil + })) + if err != nil { + log.Fatal(err) + } + + // compose graph + err = g.AddEdge(compose.START, NodeKeyInputConvert) + if err != nil { + log.Fatal(err) + } + err = g.AddEdge(NodeKeyInputConvert, NodeKeyChatModel) + if err != nil { + log.Fatal(err) + } + err = g.AddBranch(NodeKeyChatModel, compose.NewGraphBranch(func(ctx context.Context, in *schema.Message) (endNode string, err error) { + if len(in.ToolCalls) > 0 { + return NodeKeyToolsNode, nil + } + return NodeKeyHuman, nil + }, map[string]bool{ + NodeKeyToolsNode: true, + NodeKeyHuman: true, + })) + if err != nil { + log.Fatal(err) + } + err = g.AddBranch(NodeKeyHuman, compose.NewGraphBranch(func(ctx context.Context, in []*schema.Message) (endNode string, err error) { + if in[len(in)-1].Role == schema.User { + return NodeKeyChatModel, nil + } + return NodeKeyOutputConvert, nil + }, map[string]bool{ + NodeKeyChatModel: true, + NodeKeyOutputConvert: true, + })) + err = g.AddEdge(NodeKeyToolsNode, NodeKeyChatModel) + if err != nil { + log.Fatal(err) + } + err = g.AddEdge(NodeKeyOutputConvert, compose.END) + if err != nil { + log.Fatal(err) + } + + runner, err := g.Compile(ctx, compose.WithCheckPointStore(newInMemoryStore()), compose.WithInterruptBeforeNodes([]string{NodeKeyHuman})) + if err != nil { + log.Fatal(err) + } + + return runner +} + +func bindTools(ctx context.Context, cm model.ToolCallingChatModel, tools []tool.BaseTool) model.ToolCallingChatModel { + infos := make([]*schema.ToolInfo, 0, len(tools)) + for _, t := range tools { + info, err := t.Info(ctx) + if err != nil { + log.Fatal("get tool info of fail: ", err) + } + infos = append(infos, info) + } + + ncm, err := cm.WithTools(infos) + if err != nil { + log.Fatal("bind tools fail: ", err) + } + return ncm +} + +func appendNextPrompt(ctx context.Context, browserTool *browseruse.Tool) func(ctx context.Context, toolsNodeOutput []*schema.Message, state *state) ([]*schema.Message, error) { + info, err := browserTool.Info(ctx) + if err != nil { + log.Fatal("get browser tool info fail: ", err) + } + return func(ctx context.Context, toolsNodeOutput []*schema.Message, state *state) ([]*schema.Message, error) { + // append next prompt step prompt + // if call browser tool -> get browser state and append + // else append common prompt + if len(state.History) == 0 { + return toolsNodeOutput, nil + } + + llmToolCallMessage := state.History[len(state.History)-1] + for _, tc := range llmToolCallMessage.ToolCalls { + if tc.Function.Name == info.Name { + bState, err := browserTool.GetCurrentState() + if err != nil { + return nil, fmt.Errorf("failed to get browser tool state: %w", err) + } + bPrompt, err := formatBrowserToolPrompt(ctx, bState) + if err != nil { + return nil, fmt.Errorf("failed to format browser tool prompt: %w", err) + } + return append(toolsNodeOutput, bPrompt), nil + } + } + + return append(toolsNodeOutput, schema.UserMessage(nextStepPrompt)), nil + } +} + +func formatBrowserToolPrompt(ctx context.Context, bs *browseruse.BrowserState) (*schema.Message, error) { + if bs == nil { + return nil, fmt.Errorf("browser state is nil") + } + messages, err := schema.UserMessage(browserNextStepPrompt).Format(ctx, map[string]any{ + "url_placeholder": bs.URL, + "tabs_placeholder": fmt.Sprintf("%+v", bs.Tabs), + "content_above_placeholder": bs.ScrollInfo.PixelsAbove, + "content_below_placeholder": bs.ScrollInfo.PixelsBelow, + "results_placeholder": "", + }, schema.FString) + if err != nil { + return nil, err + } + message := messages[0] + if len(bs.Screenshot) > 0 { + message = schema.UserMessage("") + message.MultiContent = append(message.MultiContent, + schema.ChatMessagePart{ + Type: schema.ChatMessagePartTypeText, + Text: messages[0].Content, + }, + schema.ChatMessagePart{ + Type: schema.ChatMessagePartTypeText, + Text: "Current browser screenshot:", + }, + schema.ChatMessagePart{ + Type: schema.ChatMessagePartTypeImageURL, + ImageURL: &schema.ChatMessageImageURL{ + URL: "data:image/png;base64," + bs.Screenshot, + }, + }) + } + return message, nil +} + +func newLangfuseHandler() (*langfuse.CallbackHandler, func()) { + return langfuse.NewLangfuseHandler(&langfuse.Config{ + Host: langfuseHost, + PublicKey: langfusePublicKey, + SecretKey: langfuseSecretKey, + }) +} + +func newChatModel(ctx context.Context) model.ToolCallingChatModel { + var cm model.ToolCallingChatModel + var err error + var temp float32 = 0 + cm, err = openai.NewChatModel(ctx, &openai.ChatModelConfig{ + APIKey: openaiAPIKey, + BaseURL: openaiBaseURL, + Model: openaiModel, + Temperature: &temp, + }) + if err != nil { + log.Fatal(err) + } + return cm +} + +func newSandbox(ctx context.Context) *sandbox.DockerSandbox { + sb, err := sandbox.NewDockerSandbox(ctx, &sandbox.Config{ + Image: "python:3.9-slim", + HostName: "sandbox", + WorkDir: "/workspace", + MemoryLimit: 512 * 1024 * 1024, + CPULimit: 1.0, + NetworkEnabled: false, + Timeout: time.Second * 30, + }) + if err != nil { + log.Fatal(err) + } + err = sb.Create(ctx) + if err != nil { + log.Fatal(err) + } + return sb +} + +func newCommandLineTools(ctx context.Context, sb commandline.Operator) []tool.BaseTool { + et, err := commandline.NewStrReplaceEditor(ctx, &commandline.EditorConfig{Operator: sb}) + if err != nil { + log.Fatal(err) + } + pt, err := commandline.NewPyExecutor(ctx, &commandline.PyExecutorConfig{Command: "python3", Operator: sb}) + if err != nil { + log.Fatal(err) + } + return []tool.BaseTool{et, pt} +} + +func newBrowserTool(ctx context.Context) *browseruse.Tool { + ddgs, err := ddgsearch.New(&ddgsearch.Config{Timeout: time.Second * 30}) + if err != nil { + log.Fatal(err) + } + + t, err := browseruse.NewBrowserUseTool(ctx, &browseruse.Config{ + Headless: false, + DisableSecurity: false, + ExtraChromiumArgs: nil, + ChromeInstancePath: "", + ProxyServer: "", + DDGSearchTool: ddgs, + ExtractChatModel: newChatModel(ctx), + Logf: log.Printf, + }) + if err != nil { + log.Fatal(err) + } + return t +} + +func newInMemoryStore() *inMemoryStore { + return &inMemoryStore{m: make(map[string][]byte)} +} + +type inMemoryStore struct { + m map[string][]byte +} + +func (i *inMemoryStore) Get(ctx context.Context, checkPointID string) ([]byte, bool, error) { + data, ok := i.m[checkPointID] + return data, ok, nil +} + +func (i *inMemoryStore) Set(ctx context.Context, checkPointID string, checkPoint []byte) error { + i.m[checkPointID] = checkPoint + return nil +} diff --git a/flow/agent/manus/prompt.go b/flow/agent/manus/prompt.go new file mode 100644 index 0000000..3ae24cc --- /dev/null +++ b/flow/agent/manus/prompt.go @@ -0,0 +1,48 @@ +/* + * Copyright 2024 CloudWeGo Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +const ( + systemPrompt = ` +You are OpenManus, an all-capable AI assistant, aimed at solving any task presented by the user. You have various tools at your disposal that you can call upon to efficiently complete complex requests. Whether it's programming, information retrieval, file processing, or web browsing, you can handle it all. +` + + nextStepPrompt = ` +Based on user needs, proactively select the most appropriate tool or combination of tools. For complex tasks, you can break down the problem and use different tools step by step to solve it. After using each tool, clearly explain the execution results and suggest the next steps. +` + + browserNextStepPrompt = ` +What should I do next to achieve my goal? + +When you see [Current state starts here], focus on the following: +- Current URL and page title{url_placeholder} +- Available tabs{tabs_placeholder} +- Interactive elements and their indices +- Content above{content_above_placeholder} or below{content_below_placeholder} the viewport (if indicated) +- Any action results or errors{results_placeholder} + +For browser interactions: +- To navigate: browser_use with action="go_to_url", url="..." +- To click: browser_use with action="click_element", index=N +- To type: browser_use with action="input_text", index=N, text="..." +- To extract: browser_use with action="extract_content", goal="..." +- To scroll: browser_use with action="scroll_down" or "scroll_up" + +Consider both what's visible and what might be beyond the current viewport. +Be methodical - remember your progress and what you've learned so far. +` +) diff --git a/go.mod b/go.mod index e431167..395ff5f 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/cloudwego/eino v0.3.18 github.com/cloudwego/eino-ext/components/document/parser/html v0.0.0-20250117061805-cd80d1780d76 github.com/cloudwego/eino-ext/components/document/parser/pdf v0.0.0-20250117061805-cd80d1780d76 - github.com/cloudwego/eino-ext/components/model/ark v0.1.0 + github.com/cloudwego/eino-ext/components/model/ark v0.1.5 github.com/cloudwego/eino-ext/components/model/deepseek v0.0.0-20250221090944-e8ef7aabbe10 github.com/cloudwego/eino-ext/components/model/ollama v0.0.0-20250221090944-e8ef7aabbe10 github.com/cloudwego/eino-ext/components/model/openai v0.0.0-20250221090944-e8ef7aabbe10 diff --git a/go.sum b/go.sum index cc82bc2..b061689 100644 --- a/go.sum +++ b/go.sum @@ -110,8 +110,8 @@ github.com/cloudwego/eino-ext/components/document/parser/html v0.0.0-20250117061 github.com/cloudwego/eino-ext/components/document/parser/html v0.0.0-20250117061805-cd80d1780d76/go.mod h1:LWR+h0EfIELl/I1tDSVH0Tgx8j2gymxa174U1C8BNps= github.com/cloudwego/eino-ext/components/document/parser/pdf v0.0.0-20250117061805-cd80d1780d76 h1:GJ4OqxyBH8la8Gu4PhTHXZNZFmrtEIrrymkCEpJ7XZU= github.com/cloudwego/eino-ext/components/document/parser/pdf v0.0.0-20250117061805-cd80d1780d76/go.mod h1:swAgO0nNekTSKGgFqiy4zShKaCDhiIZoKEFwpi7NBFE= -github.com/cloudwego/eino-ext/components/model/ark v0.1.0 h1:WjOxzaFqVObKBnboNBNFmrRw1f6eldbGn5gsYR9bEUQ= -github.com/cloudwego/eino-ext/components/model/ark v0.1.0/go.mod h1:ZQndPvPwpgSWx/yDFcajBhAVQC6wgRCJwYZBcIHjaaw= +github.com/cloudwego/eino-ext/components/model/ark v0.1.5 h1:KnDkwf/8WeBbBCJ/A3h1CPtTrPxjPuPWekb6ejp4B+U= +github.com/cloudwego/eino-ext/components/model/ark v0.1.5/go.mod h1:jzdi3V2rPrfiTzCoheqaiK7/3pM5pvt8K3NRPn1oZl0= github.com/cloudwego/eino-ext/components/model/deepseek v0.0.0-20250221090944-e8ef7aabbe10 h1:9iORkTzR5fFrChi+KZyjHb1V4giJjXwBKqdvA4Q/7AM= github.com/cloudwego/eino-ext/components/model/deepseek v0.0.0-20250221090944-e8ef7aabbe10/go.mod h1:7q+/XE3qUbziFpBtszj90yfn+J0bUHCED5ImvaLFRR0= github.com/cloudwego/eino-ext/components/model/ollama v0.0.0-20250221090944-e8ef7aabbe10 h1:szRTjISOn310TwL4yJqqkvKVv9N/31g3zuhOhR9X1WI=