Compare commits
2 Commits
82580a5a7a
...
8ae16cb633
Author | SHA1 | Date | |
---|---|---|---|
8ae16cb633 | |||
24f248d900 |
27
go.mod
27
go.mod
@ -8,14 +8,14 @@ replace github.com/rocketlaunchr/google-search => github.com/chrisjoyce911/googl
|
||||
|
||||
require (
|
||||
gitea.stevedudenhoeffer.com/steve/go-extractor v0.0.0-20250318064250-39453288ce2a
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250412190744-39ffb8223775
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250502021123-e9baf7910e00
|
||||
github.com/Edw590/go-wolfram v0.0.0-20241010091529-fb9031908c5d
|
||||
github.com/advancedlogic/GoOse v0.0.0-20231203033844-ae6b36caf275
|
||||
github.com/asticode/go-astisub v0.34.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/docker/docker v28.0.2+incompatible
|
||||
github.com/joho/godotenv v1.5.1
|
||||
github.com/lrstanley/go-ytdlp v0.0.0-20250401014907-da1707e4fb85
|
||||
github.com/lrstanley/go-ytdlp v0.0.0-20250501010938-80d02fe36936
|
||||
github.com/opencontainers/image-spec v1.1.1
|
||||
github.com/playwright-community/playwright-go v0.5101.0
|
||||
github.com/rocketlaunchr/google-search v1.1.6
|
||||
@ -24,12 +24,12 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.120.0 // indirect
|
||||
cloud.google.com/go/ai v0.10.1 // indirect
|
||||
cloud.google.com/go/auth v0.15.0 // indirect
|
||||
cloud.google.com/go v0.121.0 // indirect
|
||||
cloud.google.com/go/ai v0.11.0 // indirect
|
||||
cloud.google.com/go/auth v0.16.1 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.6.0 // indirect
|
||||
cloud.google.com/go/longrunning v0.6.6 // indirect
|
||||
cloud.google.com/go/longrunning v0.6.7 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.2.0 // indirect
|
||||
github.com/PuerkitoBio/goquery v1.10.3 // indirect
|
||||
@ -42,7 +42,7 @@ require (
|
||||
github.com/asticode/go-astits v1.13.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.1 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
|
||||
github.com/deckarep/golang-set/v2 v2.8.0 // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
@ -63,7 +63,7 @@ require (
|
||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/generative-ai-go v0.19.0 // indirect
|
||||
github.com/google/generative-ai-go v0.20.1 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
@ -76,13 +76,12 @@ require (
|
||||
github.com/moby/term v0.5.2 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/openai/openai-go v0.1.0-beta.9 // indirect
|
||||
github.com/openai/openai-go v0.1.0-beta.10 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
|
||||
github.com/sashabaranov/go-openai v1.38.1 // indirect
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
||||
github.com/temoto/robotstxt v1.1.2 // indirect
|
||||
github.com/tidwall/gjson v1.18.0 // indirect
|
||||
@ -103,11 +102,11 @@ require (
|
||||
golang.org/x/sys v0.32.0 // indirect
|
||||
golang.org/x/text v0.24.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
google.golang.org/api v0.228.0 // indirect
|
||||
google.golang.org/api v0.231.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect
|
||||
google.golang.org/grpc v1.71.1 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250428153025-10db94c68c34 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250428153025-10db94c68c34 // indirect
|
||||
google.golang.org/grpc v1.72.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gotest.tools/v3 v3.5.2 // indirect
|
||||
)
|
||||
|
86
go.sum
86
go.sum
@ -1,28 +1,20 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA=
|
||||
cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q=
|
||||
cloud.google.com/go/ai v0.10.1 h1:EU93KqYmMeOKgaBXAz2DshH2C/BzAT1P+iJORksLIic=
|
||||
cloud.google.com/go/ai v0.10.1/go.mod h1:sWWHZvmJ83BjuxAQtYEiA0SFTpijtbH+SXWFO14ri5A=
|
||||
cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps=
|
||||
cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8=
|
||||
cloud.google.com/go v0.121.0 h1:pgfwva8nGw7vivjZiRfrmglGWiCJBP+0OmDpenG/Fwg=
|
||||
cloud.google.com/go v0.121.0/go.mod h1:rS7Kytwheu/y9buoDmu5EIpMMCI4Mb8ND4aeN4Vwj7Q=
|
||||
cloud.google.com/go/ai v0.11.0 h1:e0uK//+NCv70DBz8qJ0zRW90OP5kQjt27CjbHl3SG2A=
|
||||
cloud.google.com/go/ai v0.11.0/go.mod h1:bmTa0Ir0VJzDEv841PbAlQlJ/Jxv8Ab5L6LR7Z1Q/QE=
|
||||
cloud.google.com/go/auth v0.16.1 h1:XrXauHMd30LhQYVRHLGvJiYeczweKQXZxsTbV9TiguU=
|
||||
cloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
|
||||
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
|
||||
cloud.google.com/go/longrunning v0.6.6 h1:XJNDo5MUfMM05xK3ewpbSdmt7R2Zw+aQEMbdQR65Rbw=
|
||||
cloud.google.com/go/longrunning v0.6.6/go.mod h1:hyeGJUrPHcx0u2Uu1UFSoYZLn4lkMrccJig0t4FI7yw=
|
||||
cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
|
||||
cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
|
||||
gitea.stevedudenhoeffer.com/steve/go-extractor v0.0.0-20250318064250-39453288ce2a h1:LZriHuPVjdus7Haz+qEFYgr+g/eOdmeAvlbgk67DDHA=
|
||||
gitea.stevedudenhoeffer.com/steve/go-extractor v0.0.0-20250318064250-39453288ce2a/go.mod h1:fzvvUfN8ej2u1ruCsABG+D+2dAPfOklInS4b1pvog1M=
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250407055702-5ba0d5df7e96 h1:kT0pwH+q9i4TcFSRems8UFgaKCO94bCzLCf0IgAj6qw=
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250407055702-5ba0d5df7e96/go.mod h1:Puz2eDyIwyQLKFt20BU9eRrfkUpBFo+ZX+PtTI64XSo=
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250408003321-2ae583e9f360 h1:eZ8CZ1o4ZaciaDL0B/6tYwIERFZ94tNQtG7NKdb7cEQ=
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250408003321-2ae583e9f360/go.mod h1:Puz2eDyIwyQLKFt20BU9eRrfkUpBFo+ZX+PtTI64XSo=
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250412062040-3093b988f80a h1:SH2fWzDtv2KeWiwW+wtPr4NLI3CwdCSoYKn3FCRDdZc=
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250412062040-3093b988f80a/go.mod h1:RPbuI2VSwQJArwr4tdqmu+fEKlhpro5Cqtq6aC4Cp1w=
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250412074148-916f07be1840 h1:Yf33CXaCYwBG6AQxQAiK5MrdCQrRrf+Y0tzSfuXPb30=
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250412074148-916f07be1840/go.mod h1:RPbuI2VSwQJArwr4tdqmu+fEKlhpro5Cqtq6aC4Cp1w=
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250412190744-39ffb8223775 h1:KF6HdT7A5fqDnEWRjoYCm2mm5booxd+YD6j0wJkh+GU=
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250412190744-39ffb8223775/go.mod h1:RPbuI2VSwQJArwr4tdqmu+fEKlhpro5Cqtq6aC4Cp1w=
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250502021123-e9baf7910e00 h1:yPVQZG4xdENkWZi/9OLQcFSQb603ftWUTRct51Q64xc=
|
||||
gitea.stevedudenhoeffer.com/steve/go-llm v0.0.0-20250502021123-e9baf7910e00/go.mod h1:RPbuI2VSwQJArwr4tdqmu+fEKlhpro5Cqtq6aC4Cp1w=
|
||||
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/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
@ -31,15 +23,11 @@ github.com/Edw590/go-wolfram v0.0.0-20241010091529-fb9031908c5d h1:dxGZ0drmrUfNO
|
||||
github.com/Edw590/go-wolfram v0.0.0-20241010091529-fb9031908c5d/go.mod h1:ubjYqrt3dF4G+YVEDQr+qa2aveeMzt27o/GOH2hswPo=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw=
|
||||
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/ProtonMail/go-crypto v1.2.0 h1:+PhXXn4SPGd+qk76TlEePBfOfivE0zkWFenhGhFLzWs=
|
||||
github.com/ProtonMail/go-crypto v1.2.0/go.mod h1:9whxjD8Rbs29b4XWbB8irEcE8KHMqaR2e7GWU1R+/PE=
|
||||
github.com/PuerkitoBio/goquery v1.4.1/go.mod h1:T9ezsOHcCrDCgA8aF1Cqr3sSYbO/xgdy8/R/XiIMAhA=
|
||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
|
||||
github.com/PuerkitoBio/goquery v1.10.2 h1:7fh2BdHcG6VFZsK7toXBT/Bh1z5Wmy8Q9MV9HqT2AM8=
|
||||
github.com/PuerkitoBio/goquery v1.10.2/go.mod h1:0guWGjcLu9AYC7C1GHnpysHy056u9aEkUHwhdnePMCU=
|
||||
github.com/PuerkitoBio/goquery v1.10.3 h1:pFYcNSqHxBD06Fpj/KsbStFRsgRATgnf3LeXiUkhzPo=
|
||||
github.com/PuerkitoBio/goquery v1.10.3/go.mod h1:tMUX0zDMHXYlAQk6p35XxQMqMweEKB7iK7iLNd4RH4Y=
|
||||
github.com/advancedlogic/GoOse v0.0.0-20231203033844-ae6b36caf275 h1:Kuhf+w+ilOGoXaR4O4nZ6Dp+ZS83LdANUjwyMXsPGX4=
|
||||
@ -83,15 +71,13 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
|
||||
github.com/chrisjoyce911/google-search v0.0.0-20230910003754-e501aedf805a h1:OZQiBySVd55npXVsIKnJT6q+9A1tPiXhGnFlc+q0YqQ=
|
||||
github.com/chrisjoyce911/google-search v0.0.0-20230910003754-e501aedf805a/go.mod h1:fk5J/qPpaRDjLWdFxT+dmuiqG7kxXArC7K8A+gj88Nk=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk=
|
||||
github.com/cloudflare/circl v1.6.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
|
||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
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=
|
||||
@ -159,8 +145,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/generative-ai-go v0.19.0 h1:R71szggh8wHMCUlEMsW2A/3T+5LdEIkiaHSYgSpUgdg=
|
||||
github.com/google/generative-ai-go v0.19.0/go.mod h1:JYolL13VG7j79kM5BtHz4qwONHkeJQzOCkKXnpqtS/E=
|
||||
github.com/google/generative-ai-go v0.20.1 h1:6dEIujpgN2V0PgLhr6c/M1ynRdc7ARtiIDPFzj45uNQ=
|
||||
github.com/google/generative-ai-go v0.20.1/go.mod h1:TjOnZJmZKzarWbjUJgy+r3Ee7HGBRVLhOIgupnwR4Bg=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
@ -192,8 +178,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/liushuangls/go-anthropic/v2 v2.15.0 h1:zpplg7BRV/9FlMmeMPI0eDwhViB0l9SkNrF8ErYlRoQ=
|
||||
github.com/liushuangls/go-anthropic/v2 v2.15.0/go.mod h1:kq2yW3JVy1/rph8u5KzX7F3q95CEpCT2RXp/2nfCmb4=
|
||||
github.com/lrstanley/go-ytdlp v0.0.0-20250401014907-da1707e4fb85 h1:fgU9HcQ95uG9vqkYP/YW/H6DhwsmkXHriuMM27bwpYU=
|
||||
github.com/lrstanley/go-ytdlp v0.0.0-20250401014907-da1707e4fb85/go.mod h1:HpxGaeaOpXVUPxUUmj8Izr3helrDGN90haPtmpY5xzA=
|
||||
github.com/lrstanley/go-ytdlp v0.0.0-20250501010938-80d02fe36936 h1:hYa4l1wvSl9OHHgfNemq8I/L1iyWl2KGVp43GMwTGzQ=
|
||||
github.com/lrstanley/go-ytdlp v0.0.0-20250501010938-80d02fe36936/go.mod h1:HpxGaeaOpXVUPxUUmj8Izr3helrDGN90haPtmpY5xzA=
|
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
@ -210,12 +196,8 @@ github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7P
|
||||
github.com/olekukonko/tablewriter v0.0.0-20180506121414-d4647c9c7a84/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/openai/openai-go v0.1.0-beta.6 h1:JquYDpprfrGnlKvQQg+apy9dQ8R9mIrm+wNvAPp6jCQ=
|
||||
github.com/openai/openai-go v0.1.0-beta.6/go.mod h1:g461MYGXEXBVdV5SaR/5tNzNbSfwTBBefwc+LlDCK0Y=
|
||||
github.com/openai/openai-go v0.1.0-beta.7 h1:ykC09BCIgdXL69wE/8NUjL2rCdAbo9kL3AjnGR6H91o=
|
||||
github.com/openai/openai-go v0.1.0-beta.7/go.mod h1:g461MYGXEXBVdV5SaR/5tNzNbSfwTBBefwc+LlDCK0Y=
|
||||
github.com/openai/openai-go v0.1.0-beta.9 h1:ABpubc5yU/3ejee2GgRrbFta81SG/d7bQbB8mIdP0Xo=
|
||||
github.com/openai/openai-go v0.1.0-beta.9/go.mod h1:g461MYGXEXBVdV5SaR/5tNzNbSfwTBBefwc+LlDCK0Y=
|
||||
github.com/openai/openai-go v0.1.0-beta.10 h1:CknhGXe8aXQMRuqg255PFnWzgRY9nEryMxoNIBBM9tU=
|
||||
github.com/openai/openai-go v0.1.0-beta.10/go.mod h1:g461MYGXEXBVdV5SaR/5tNzNbSfwTBBefwc+LlDCK0Y=
|
||||
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=
|
||||
@ -224,8 +206,6 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.4.0/go.mod h1:NWz/XGvpEW1FyYQ7fCx4dqYBLlfTcE+A9FLAkNKqjFE=
|
||||
github.com/playwright-community/playwright-go v0.5001.0 h1:EY3oB+rU9cUp6CLHguWE8VMZTwAg+83Yyb7dQqEmGLg=
|
||||
github.com/playwright-community/playwright-go v0.5001.0/go.mod h1:kBNWs/w2aJ2ZUp1wEOOFLXgOqvppFngM5OS+qyhl+ZM=
|
||||
github.com/playwright-community/playwright-go v0.5101.0 h1:gVCMZThDO76LJ/aCI27lpB8hEAWhZszeS0YB+oTxJp0=
|
||||
github.com/playwright-community/playwright-go v0.5101.0/go.mod h1:kBNWs/w2aJ2ZUp1wEOOFLXgOqvppFngM5OS+qyhl+ZM=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@ -235,15 +215,11 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
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/sashabaranov/go-openai v1.38.1 h1:TtZabbFQZa1nEni/IhVtDF/WQjVqDgd+cWR5OeddzF8=
|
||||
github.com/sashabaranov/go-openai v1.38.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
|
||||
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
@ -359,8 +335,6 @@ golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -447,8 +421,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
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/api v0.228.0 h1:X2DJ/uoWGnY5obVjewbp8icSL5U4FzuCfy9OjbLSnLs=
|
||||
google.golang.org/api v0.228.0/go.mod h1:wNvRS1Pbe8r4+IfBIniV8fwCpGwTrYa+kMUDiC5z5a4=
|
||||
google.golang.org/api v0.231.0 h1:LbUD5FUl0C4qwia2bjXhCMH65yz1MLPzA/0OYEsYY7Q=
|
||||
google.golang.org/api v0.231.0/go.mod h1:H52180fPI/QQlUc0F4xWfGZILdv09GCWKt2bcsn164A=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
@ -458,23 +432,15 @@ google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJ
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250404141209-ee84b53bf3d0 h1:Qbb5RVn5xzI4naMJSpJ7lhvmos6UwZkbekd5Uz7rt9E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250404141209-ee84b53bf3d0/go.mod h1:6T35kB3IPpdw7Wul09by0G/JuOuIFkXV6OOvt8IZeT8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250407143221-ac9807e6c755 h1:AMLTAunltONNuzWgVPZXrjLWtXpsG6A3yLLPEoJ/IjU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250407143221-ac9807e6c755/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250404141209-ee84b53bf3d0 h1:0K7wTWyzxZ7J+L47+LbFogJW1nn/gnnMCN0vGXNYtTI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250404141209-ee84b53bf3d0/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250407143221-ac9807e6c755 h1:TwXJCGVREgQ/cl18iY0Z4wJCTL/GmW+Um2oSwZiZPnc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250407143221-ac9807e6c755/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250428153025-10db94c68c34 h1:0PeQib/pH3nB/5pEmFeVQJotzGohV0dq4Vcp09H5yhE=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250428153025-10db94c68c34/go.mod h1:0awUlEkap+Pb1UMeJwJQQAdJQrt3moU7J2moTy69irI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250428153025-10db94c68c34 h1:h6p3mQqrmT1XkHVTfzLdNz1u7IhINeZkz67/xTbOuWs=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250428153025-10db94c68c34/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
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/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM=
|
||||
google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
|
@ -12,12 +12,14 @@ import (
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/client"
|
||||
|
||||
gollm "gitea.stevedudenhoeffer.com/steve/go-llm"
|
||||
|
||||
"gitea.stevedudenhoeffer.com/steve/answer/pkg/agents"
|
||||
"gitea.stevedudenhoeffer.com/steve/answer/pkg/agents/shared"
|
||||
gollm "gitea.stevedudenhoeffer.com/steve/go-llm"
|
||||
)
|
||||
|
||||
type Agent struct {
|
||||
agents.Agent
|
||||
// Model is the chat completion model to use
|
||||
Model gollm.ChatCompletion
|
||||
|
||||
@ -35,7 +37,8 @@ type Agent struct {
|
||||
|
||||
type Response struct {
|
||||
Knowledge agents.Knowledge
|
||||
Directory string
|
||||
DataDir string
|
||||
OutputDir string
|
||||
}
|
||||
|
||||
// Answer will give the model access to an ubuntu console with python and pip installed, and then ask the model to
|
||||
@ -43,8 +46,10 @@ type Response struct {
|
||||
func (a Agent) Answer(ctx context.Context, questions []string) (Response, error) {
|
||||
var res Response
|
||||
|
||||
a.Agent = agents.NewAgent(a.Model, gollm.NewToolBox()).WithMaxCalls(200)
|
||||
|
||||
if a.MaxCommands <= 0 {
|
||||
a.MaxCommands = 10000
|
||||
a.MaxCommands = 20 // Default to 20 commands as per requirements
|
||||
}
|
||||
|
||||
res.Knowledge = agents.Knowledge{
|
||||
@ -52,16 +57,25 @@ func (a Agent) Answer(ctx context.Context, questions []string) (Response, error)
|
||||
RemainingQuestions: questions,
|
||||
}
|
||||
|
||||
// create a temporary scratch directory
|
||||
dir, err := os.MkdirTemp("", "console-")
|
||||
// create temporary directories for data and output
|
||||
dataDir, err := os.MkdirTemp("", "console-data-")
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
res.Directory = dir
|
||||
outputDir, err := os.MkdirTemp("", "console-output-")
|
||||
if err != nil {
|
||||
os.RemoveAll(dataDir)
|
||||
return res, err
|
||||
}
|
||||
|
||||
res.DataDir = dataDir
|
||||
res.OutputDir = outputDir
|
||||
|
||||
cl, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
os.RemoveAll(dataDir)
|
||||
os.RemoveAll(outputDir)
|
||||
return res, err
|
||||
}
|
||||
defer cl.Close()
|
||||
@ -69,8 +83,13 @@ func (a Agent) Answer(ctx context.Context, questions []string) (Response, error)
|
||||
mounts := []mount.Mount{
|
||||
{
|
||||
Type: mount.TypeBind,
|
||||
Source: dir,
|
||||
Target: "/home/user",
|
||||
Source: dataDir,
|
||||
Target: "/data",
|
||||
},
|
||||
{
|
||||
Type: mount.TypeBind,
|
||||
Source: outputDir,
|
||||
Target: "/output",
|
||||
},
|
||||
}
|
||||
|
||||
@ -79,25 +98,29 @@ func (a Agent) Answer(ctx context.Context, questions []string) (Response, error)
|
||||
Image: "ubuntu:latest",
|
||||
Cmd: []string{"tail", "-f", "/dev/null"},
|
||||
Tty: true,
|
||||
WorkingDir: "/home/user",
|
||||
WorkingDir: "/data",
|
||||
},
|
||||
HostConfig: &container.HostConfig{
|
||||
AutoRemove: true,
|
||||
Mounts: mounts,
|
||||
},
|
||||
Name: filepath.Base(dir),
|
||||
Name: filepath.Base(dataDir),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
os.RemoveAll(dataDir)
|
||||
os.RemoveAll(outputDir)
|
||||
return res, fmt.Errorf("failed to create container: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
_ = c.Close(ctx)
|
||||
}()
|
||||
|
||||
slog.Info("starting container", "dir", dir, "container", fmt.Sprintf("%+v", c))
|
||||
slog.Info("starting container", "dataDir", dataDir, "outputDir", outputDir, "container", fmt.Sprintf("%+v", c))
|
||||
err = c.Start(ctx)
|
||||
if err != nil {
|
||||
os.RemoveAll(dataDir)
|
||||
os.RemoveAll(outputDir)
|
||||
return res, fmt.Errorf("failed to start container: %w", err)
|
||||
}
|
||||
|
||||
@ -106,12 +129,17 @@ func (a Agent) Answer(ctx context.Context, questions []string) (Response, error)
|
||||
var history executions
|
||||
var keepGoing = true
|
||||
|
||||
opwd, epwd := c.Execute(ctx, "ls -al /home")
|
||||
// Initial setup - install basic tools
|
||||
setupCmd, setupErr := c.Sudo(ctx, "apt-get update && apt-get install -y curl wget git python3 python3-pip")
|
||||
if setupErr == nil {
|
||||
history = append(history, execution{
|
||||
Command: "sudo apt-get update && apt-get install -y curl wget git python3 python3-pip",
|
||||
Output: setupCmd,
|
||||
WhatILearned: []string{"Basic tools installed: curl, wget, git, python3, pip"},
|
||||
})
|
||||
}
|
||||
|
||||
fmt.Println(opwd)
|
||||
slog.Info("pwd", "pwd", opwd, "epwd", epwd)
|
||||
|
||||
tools := map[string]*gollm.Function{
|
||||
tools := map[string]gollm.Function{
|
||||
"exit": gollm.NewFunction(
|
||||
"exit",
|
||||
"exit the container",
|
||||
@ -122,18 +150,24 @@ func (a Agent) Answer(ctx context.Context, questions []string) (Response, error)
|
||||
return "exiting", nil
|
||||
}),
|
||||
|
||||
"write": gollm.NewFunction(
|
||||
"write",
|
||||
"write a file in the /root directory",
|
||||
"write_data": gollm.NewFunction(
|
||||
"write_data",
|
||||
"write a file in the /data directory",
|
||||
func(ctx *gollm.Context, args struct {
|
||||
Filename string `description:"The name of the file to write"`
|
||||
Content string `description:"The content of the file to write"`
|
||||
}) (any, error) {
|
||||
target, err := SafeJoinPath(dir, args.Filename)
|
||||
target, err := SafeJoinPath(dataDir, args.Filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Ensure directory exists
|
||||
dir := filepath.Dir(target)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
f, err := os.Create(target)
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -145,16 +179,67 @@ func (a Agent) Answer(ctx context.Context, questions []string) (Response, error)
|
||||
return "", err
|
||||
}
|
||||
|
||||
return "wrote file", nil
|
||||
return "wrote file to /data/" + args.Filename, nil
|
||||
}),
|
||||
|
||||
"read": gollm.NewFunction(
|
||||
"read",
|
||||
"read a file in the /root directory",
|
||||
"write_output": gollm.NewFunction(
|
||||
"write_output",
|
||||
"write a file in the /output directory (files here will be available after the agent completes)",
|
||||
func(ctx *gollm.Context, args struct {
|
||||
Filename string `description:"The name of the file to write"`
|
||||
Content string `description:"The content of the file to write"`
|
||||
}) (any, error) {
|
||||
target, err := SafeJoinPath(outputDir, args.Filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Ensure directory exists
|
||||
dir := filepath.Dir(target)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
f, err := os.Create(target)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
_, err = f.WriteString(args.Content)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return "wrote file to /output/" + args.Filename, nil
|
||||
}),
|
||||
|
||||
"read_data": gollm.NewFunction(
|
||||
"read_data",
|
||||
"read a file from the /data directory",
|
||||
func(ctx *gollm.Context, args struct {
|
||||
Filename string `description:"The name of the file to read"`
|
||||
}) (any, error) {
|
||||
target, err := SafeJoinPath(dir, args.Filename)
|
||||
target, err := SafeJoinPath(dataDir, args.Filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
b, err := os.ReadFile(target)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(b), nil
|
||||
}),
|
||||
|
||||
"read_output": gollm.NewFunction(
|
||||
"read_output",
|
||||
"read a file from the /output directory",
|
||||
func(ctx *gollm.Context, args struct {
|
||||
Filename string `description:"The name of the file to read"`
|
||||
}) (any, error) {
|
||||
target, err := SafeJoinPath(outputDir, args.Filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -171,10 +256,12 @@ func (a Agent) Answer(ctx context.Context, questions []string) (Response, error)
|
||||
"execute",
|
||||
"execute a command in the container",
|
||||
func(ctx *gollm.Context, args struct {
|
||||
Command string `description:"The command to execute"`
|
||||
Command string `description:"The command to execute"`
|
||||
Learn []string `description:"What you learned from this command (optional)"`
|
||||
ToLearn []string `description:"What you still need to learn (optional)"`
|
||||
}) (any, error) {
|
||||
if len(history) >= a.MaxCommands {
|
||||
return "too many commands", nil
|
||||
return "Command limit reached. You've used all " + fmt.Sprintf("%d", a.MaxCommands) + " allowed commands.", nil
|
||||
}
|
||||
|
||||
if a.OnCommandStart != nil {
|
||||
@ -200,71 +287,79 @@ func (a Agent) Answer(ctx context.Context, questions []string) (Response, error)
|
||||
}
|
||||
|
||||
history = append(history, execution{
|
||||
Command: args.Command,
|
||||
Output: res,
|
||||
Command: args.Command,
|
||||
Output: res,
|
||||
WhatILearned: args.Learn,
|
||||
WhatIStillNeedToLearn: args.ToLearn,
|
||||
})
|
||||
|
||||
return res, nil
|
||||
}),
|
||||
|
||||
"sudo": gollm.NewFunction(
|
||||
"sudo",
|
||||
"execute a command in the container",
|
||||
func(ctx *gollm.Context, args struct {
|
||||
Command string `description:"The command to execute"`
|
||||
}) (any, error) {
|
||||
if len(history) >= a.MaxCommands {
|
||||
return "too many commands", nil
|
||||
"summarize_knowledge": gollm.NewFunction(
|
||||
"summarize_knowledge",
|
||||
"summarize what you've learned so far",
|
||||
func(ctx *gollm.Context, args struct{}) (any, error) {
|
||||
var learned []string
|
||||
var toLearn []string
|
||||
|
||||
for _, exec := range history {
|
||||
learned = append(learned, exec.WhatILearned...)
|
||||
toLearn = append(toLearn, exec.WhatIStillNeedToLearn...)
|
||||
}
|
||||
|
||||
if a.OnCommandStart != nil {
|
||||
err := a.OnCommandStart(ctx, args.Command)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
summary := "Knowledge Summary:\n"
|
||||
if len(learned) > 0 {
|
||||
summary += "What I've learned:\n- " + strings.Join(learned, "\n- ") + "\n\n"
|
||||
} else {
|
||||
summary += "I haven't learned anything specific yet.\n\n"
|
||||
}
|
||||
|
||||
res, err := c.Sudo(ctx, args.Command)
|
||||
|
||||
if a.OnCommandDone != nil {
|
||||
err = a.OnCommandDone(ctx, args.Command, res, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(toLearn) > 0 {
|
||||
summary += "What I still need to learn:\n- " + strings.Join(toLearn, "\n- ")
|
||||
} else {
|
||||
summary += "I don't have any specific learning goals at the moment."
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
res = "error executing: " + err.Error()
|
||||
}
|
||||
|
||||
history = append(history, execution{
|
||||
Command: "sudo " + args.Command,
|
||||
Output: res,
|
||||
})
|
||||
|
||||
return res, nil
|
||||
return summary, nil
|
||||
}),
|
||||
}
|
||||
|
||||
for i := 0; i < a.MaxCommands && len(history) < a.MaxCommands && keepGoing; i++ {
|
||||
|
||||
systemPrompt := `You are now in a shell in a container of the ubuntu:latest image to answer a question asked by the user, it is very basic install of ubuntu, simple things (like python) are not preinstalled but can be installed via apt. You will be run multiple times and gain knowledge throughout the process.`
|
||||
systemPrompt := `You are now in a shell in a container of the ubuntu:latest image to answer a question asked by the user.
|
||||
You have full control over a bash shell inside this Docker container.
|
||||
|
||||
Important directories:
|
||||
- /data: A temporary directory with the lifespan of your processing. Use this for working files.
|
||||
- /output: Files placed here will be returned to the caller after you're done. Use this for final results.
|
||||
|
||||
You can execute up to ` + fmt.Sprintf("%d", a.MaxCommands) + ` commands total. You're currently on command ` + fmt.Sprintf("%d", len(history)+1) + ` of ` + fmt.Sprintf("%d", a.MaxCommands) + `.
|
||||
|
||||
For each command, you should:
|
||||
1. Think about what you need to learn
|
||||
2. Execute the command using the "execute" function
|
||||
3. Analyze the output and record what you learned
|
||||
4. Plan your next command based on this knowledge
|
||||
|
||||
You can write files directly to /data or /output using the write_data and write_output functions.
|
||||
When you are done, use "exit" to exit the container.`
|
||||
|
||||
var toolbox []gollm.Function
|
||||
|
||||
// Add all tools
|
||||
toolbox = append(toolbox,
|
||||
tools["exit"],
|
||||
tools["write_data"],
|
||||
tools["write_output"],
|
||||
tools["read_data"],
|
||||
tools["read_output"],
|
||||
tools["summarize_knowledge"],
|
||||
)
|
||||
|
||||
// Only add execute if we haven't reached the command limit
|
||||
if len(history) < a.MaxCommands {
|
||||
systemPrompt += `You can run any command you like to get to the needed results.`
|
||||
}
|
||||
|
||||
systemPrompt += `Alternatively, you can use the tool "write" to write a file in the home directory, and also the tool "read" to read a file in the home directory.
|
||||
When you are done, please use "exit" to exit the container.
|
||||
Respond with any number of commands to answer the question, they will be executed in order.`
|
||||
|
||||
var toolbox []*gollm.Function
|
||||
|
||||
// add unrestricted tools
|
||||
toolbox = append(toolbox, tools["exit"], tools["write"], tools["read"])
|
||||
|
||||
if len(history) < a.MaxCommands {
|
||||
toolbox = append(toolbox, tools["execute"], tools["sudo"])
|
||||
toolbox = append(toolbox, tools["execute"])
|
||||
}
|
||||
|
||||
kw := shared.KnowledgeWorker{
|
||||
@ -291,7 +386,7 @@ Respond with any number of commands to answer the question, they will be execute
|
||||
slog.Info("answered question and learned nothing")
|
||||
}
|
||||
|
||||
res.Knowledge, err = agents.KnowledgeIntegrate(ctx, a.Model, res.Knowledge, r)
|
||||
res.Knowledge, err = a.KnowledgeIntegrate(ctx, res.Knowledge, r)
|
||||
if err != nil {
|
||||
return res, fmt.Errorf("error integrating knowledge: %w", err)
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ import (
|
||||
)
|
||||
|
||||
type Agent struct {
|
||||
agents.Agent
|
||||
|
||||
// Model is the chat completion model to use
|
||||
Model gollm.ChatCompletion
|
||||
|
||||
@ -42,6 +44,7 @@ type Response struct {
|
||||
// do what is necessary to answer the question.
|
||||
func (a Agent) Answer(ctx context.Context, questions []string) (Response, error) {
|
||||
var res Response
|
||||
a.Agent = agents.NewAgent(a.Model, gollm.NewToolBox()).WithMaxCalls(200)
|
||||
|
||||
if a.MaxCommands <= 0 {
|
||||
a.MaxCommands = 10000
|
||||
@ -111,7 +114,7 @@ func (a Agent) Answer(ctx context.Context, questions []string) (Response, error)
|
||||
fmt.Println(opwd)
|
||||
slog.Info("pwd", "pwd", opwd, "epwd", epwd)
|
||||
|
||||
tools := map[string]*gollm.Function{
|
||||
tools := map[string]gollm.Function{
|
||||
"exit": gollm.NewFunction(
|
||||
"exit",
|
||||
"exit the container",
|
||||
@ -258,7 +261,7 @@ func (a Agent) Answer(ctx context.Context, questions []string) (Response, error)
|
||||
When you are done, please use "exit" to exit the container.
|
||||
Respond with any number of commands to answer the question, they will be executed in order.`
|
||||
|
||||
var toolbox []*gollm.Function
|
||||
var toolbox []gollm.Function
|
||||
|
||||
// add unrestricted tools
|
||||
toolbox = append(toolbox, tools["exit"], tools["write"], tools["read"])
|
||||
@ -291,7 +294,7 @@ Respond with any number of commands to answer the question, they will be execute
|
||||
slog.Info("answered question and learned nothing")
|
||||
}
|
||||
|
||||
res.Knowledge, err = agents.KnowledgeIntegrate(ctx, a.Model, res.Knowledge, r)
|
||||
res.Knowledge, err = a.KnowledgeIntegrate(ctx, res.Knowledge, r)
|
||||
if err != nil {
|
||||
return res, fmt.Errorf("error integrating knowledge: %w", err)
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
|
||||
type KnowledgeWorker struct {
|
||||
Model gollm.ChatCompletion
|
||||
ToolBox *gollm.ToolBox
|
||||
ToolBox gollm.ToolBox
|
||||
ContextualInformation []string
|
||||
OnNewFunction func(ctx context.Context, funcName string, args string) (any, error)
|
||||
OnFunctionFinished func(ctx context.Context, funcName string, args string, result any, err error, newFunctionResult any) error
|
||||
|
Loading…
x
Reference in New Issue
Block a user