Allow to configure connectors
This commit is contained in:
@@ -87,6 +87,10 @@ func (a *Agent) StopAction() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Agent) Context() context.Context {
|
||||||
|
return a.context.Context
|
||||||
|
}
|
||||||
|
|
||||||
// Ask is a pre-emptive, blocking call that returns the response as soon as it's ready.
|
// Ask is a pre-emptive, blocking call that returns the response as soon as it's ready.
|
||||||
// It discards any other computation.
|
// It discards any other computation.
|
||||||
func (a *Agent) Ask(opts ...JobOption) *JobResult {
|
func (a *Agent) Ask(opts ...JobOption) *JobResult {
|
||||||
|
|||||||
@@ -7,19 +7,21 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mudler/local-agent-framework/example/webui/connector"
|
||||||
|
|
||||||
. "github.com/mudler/local-agent-framework/agent"
|
. "github.com/mudler/local-agent-framework/agent"
|
||||||
"github.com/mudler/local-agent-framework/external"
|
"github.com/mudler/local-agent-framework/external"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ConnectorConfig struct {
|
type ConnectorConfig struct {
|
||||||
Type string `json:"type"` // e.g. Slack
|
Type string `json:"type"` // e.g. Slack
|
||||||
Config map[string]interface{} `json:"config"`
|
Config string `json:"config"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ActionsConfig string
|
type ActionsConfig string
|
||||||
|
|
||||||
type AgentConfig struct {
|
type AgentConfig struct {
|
||||||
Connector []ConnectorConfig `json:"connector" form:"connector" `
|
Connector []ConnectorConfig `json:"connectors" form:"connectors" `
|
||||||
Actions []ActionsConfig `json:"actions" form:"actions"`
|
Actions []ActionsConfig `json:"actions" form:"actions"`
|
||||||
// This is what needs to be part of ActionsConfig
|
// This is what needs to be part of ActionsConfig
|
||||||
Model string `json:"model" form:"model"`
|
Model string `json:"model" form:"model"`
|
||||||
@@ -111,7 +113,12 @@ func (a *AgentPool) List() []string {
|
|||||||
return agents
|
return agents
|
||||||
}
|
}
|
||||||
|
|
||||||
var AvailableActions = []string{"search"}
|
const (
|
||||||
|
ConnectorTelegram = "telegram"
|
||||||
|
ActionSearch = "search"
|
||||||
|
)
|
||||||
|
|
||||||
|
var AvailableActions = []string{ActionSearch}
|
||||||
|
|
||||||
func (a *AgentConfig) availableActions() []Action {
|
func (a *AgentConfig) availableActions() []Action {
|
||||||
actions := []Action{}
|
actions := []Action{}
|
||||||
@@ -123,7 +130,7 @@ func (a *AgentConfig) availableActions() []Action {
|
|||||||
for _, action := range a.Actions {
|
for _, action := range a.Actions {
|
||||||
fmt.Println("Set Action", action)
|
fmt.Println("Set Action", action)
|
||||||
switch action {
|
switch action {
|
||||||
case "search":
|
case ActionSearch:
|
||||||
actions = append(actions, external.NewSearch(3))
|
actions = append(actions, external.NewSearch(3))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,6 +138,39 @@ func (a *AgentConfig) availableActions() []Action {
|
|||||||
return actions
|
return actions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Connector interface {
|
||||||
|
AgentResultCallback() func(state ActionState)
|
||||||
|
AgentReasoningCallback() func(state ActionCurrentState) bool
|
||||||
|
Start(a *Agent)
|
||||||
|
}
|
||||||
|
|
||||||
|
var AvailableConnectors = []string{ConnectorTelegram}
|
||||||
|
|
||||||
|
func (a *AgentConfig) availableConnectors() []Connector {
|
||||||
|
connectors := []Connector{}
|
||||||
|
|
||||||
|
for _, c := range a.Connector {
|
||||||
|
fmt.Println("Set Connector", c)
|
||||||
|
switch c.Type {
|
||||||
|
case ConnectorTelegram:
|
||||||
|
var config map[string]string
|
||||||
|
if err := json.Unmarshal([]byte(c.Config), &config); err != nil {
|
||||||
|
fmt.Println("Error unmarshalling connector config", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Println("Config", config)
|
||||||
|
cc, err := connector.NewTelegramConnector(config)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error creating telegram connector", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
connectors = append(connectors, cc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return connectors
|
||||||
|
}
|
||||||
|
|
||||||
func (a *AgentPool) startAgentWithConfig(name string, config *AgentConfig) error {
|
func (a *AgentPool) startAgentWithConfig(name string, config *AgentConfig) error {
|
||||||
manager := NewManager(5)
|
manager := NewManager(5)
|
||||||
model := a.model
|
model := a.model
|
||||||
@@ -140,6 +180,9 @@ func (a *AgentPool) startAgentWithConfig(name string, config *AgentConfig) error
|
|||||||
if config.PeriodicRuns == "" {
|
if config.PeriodicRuns == "" {
|
||||||
config.PeriodicRuns = "10m"
|
config.PeriodicRuns = "10m"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
connectors := config.availableConnectors()
|
||||||
|
|
||||||
fmt.Println("Creating agent", name)
|
fmt.Println("Creating agent", name)
|
||||||
fmt.Println("Model", model)
|
fmt.Println("Model", model)
|
||||||
fmt.Println("API URL", a.apiURL)
|
fmt.Println("API URL", a.apiURL)
|
||||||
@@ -165,6 +208,12 @@ func (a *AgentPool) startAgentWithConfig(name string, config *AgentConfig) error
|
|||||||
fmt.Sprintf(`Thinking: %s`, htmlIfy(state.Reasoning)),
|
fmt.Sprintf(`Thinking: %s`, htmlIfy(state.Reasoning)),
|
||||||
).WithEvent("status"),
|
).WithEvent("status"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
for _, c := range connectors {
|
||||||
|
if !c.AgentReasoningCallback()(state) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}),
|
}),
|
||||||
WithAgentResultCallback(func(state ActionState) {
|
WithAgentResultCallback(func(state ActionState) {
|
||||||
@@ -185,6 +234,10 @@ func (a *AgentPool) startAgentWithConfig(name string, config *AgentConfig) error
|
|||||||
),
|
),
|
||||||
).WithEvent("status"),
|
).WithEvent("status"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
for _, c := range connectors {
|
||||||
|
c.AgentResultCallback()(state)
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
if config.HUD {
|
if config.HUD {
|
||||||
@@ -220,6 +273,10 @@ func (a *AgentPool) startAgentWithConfig(name string, config *AgentConfig) error
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
for _, c := range connectors {
|
||||||
|
go c.Start(agent)
|
||||||
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
time.Sleep(1 * time.Second) // Send a message every seconds
|
time.Sleep(1 * time.Second) // Send a message every seconds
|
||||||
|
|||||||
@@ -18,12 +18,40 @@
|
|||||||
<input type="text" name="name" id="name" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder="Name">
|
<input type="text" name="name" id="name" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder="Name">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--
|
|
||||||
<div class="mb-4">
|
<div id="connectorsSection">
|
||||||
<label for="connector" class="block text-sm font-medium text-gray-400">Connector Config (JSON)</label>
|
<div class="connector mb-4">
|
||||||
<textarea id="connector" name="connector" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder='[{"...":"..."}]'></textarea>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
-->
|
<button type="button" id="addConnectorButton" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-500 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
||||||
|
Add Connector
|
||||||
|
</button>
|
||||||
|
<script>
|
||||||
|
document.getElementById('addConnectorButton').addEventListener('click', function() {
|
||||||
|
const connectorsSection = document.getElementById('connectorsSection');
|
||||||
|
const newConnectorIndex = connectorsSection.getElementsByClassName('connector').length;
|
||||||
|
|
||||||
|
const newConnectorHTML = `
|
||||||
|
<div class="connector mb-4">
|
||||||
|
<div class="mb-4">
|
||||||
|
<label for="connectorType${newConnectorIndex}" class="block text-sm font-medium text-gray-400">Connector Type</label>
|
||||||
|
<select name="connectors[${newConnectorIndex}].type" id="connectorType${newConnectorIndex}" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white">
|
||||||
|
{{ range .Connectors }}
|
||||||
|
<option value="{{.}}">{{.}}</option>
|
||||||
|
{{ end }}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-4">
|
||||||
|
<label for="connectorConfig${newConnectorIndex}" class="block text-sm font-medium text-gray-400">Connector Config (JSON)</label>
|
||||||
|
<textarea id="connectorConfig${newConnectorIndex}" name="connectors[${newConnectorIndex}].config" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white" placeholder='{"token":"..."}'></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
connectorsSection.insertAdjacentHTML('beforeend', newConnectorHTML);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<div class="mb-4" id="action_box">
|
<div class="mb-4" id="action_box">
|
||||||
<label for="actions" class="block text-sm font-medium text-gray-400">Agent Actions</label>
|
<label for="actions" class="block text-sm font-medium text-gray-400">Agent Actions</label>
|
||||||
<select style="display: none" name="actions" id="actions" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white">
|
<select style="display: none" name="actions" id="actions" class="mt-1 focus:ring-blue-500 focus:border-blue-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md bg-gray-700 text-white">
|
||||||
|
|||||||
@@ -88,8 +88,9 @@ func main() {
|
|||||||
|
|
||||||
webapp.Get("/create", func(c *fiber.Ctx) error {
|
webapp.Get("/create", func(c *fiber.Ctx) error {
|
||||||
return c.Render("create.html", fiber.Map{
|
return c.Render("create.html", fiber.Map{
|
||||||
"Title": "Hello, World!",
|
"Title": "Hello, World!",
|
||||||
"Actions": AvailableActions,
|
"Actions": AvailableActions,
|
||||||
|
"Connectors": AvailableConnectors,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
1
go.mod
1
go.mod
@@ -20,6 +20,7 @@ require (
|
|||||||
github.com/andybalholm/cascadia v1.1.0 // indirect
|
github.com/andybalholm/cascadia v1.1.0 // indirect
|
||||||
github.com/go-logr/logr v1.3.0 // indirect
|
github.com/go-logr/logr v1.3.0 // indirect
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||||
|
github.com/go-telegram/bot v1.2.1 // indirect
|
||||||
github.com/gofiber/fiber/v2 v2.52.4 // indirect
|
github.com/gofiber/fiber/v2 v2.52.4 // indirect
|
||||||
github.com/gofiber/utils/v2 v2.0.0-beta.4 // indirect
|
github.com/gofiber/utils/v2 v2.0.0-beta.4 // indirect
|
||||||
github.com/google/go-cmp v0.6.0 // indirect
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -16,6 +16,8 @@ github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
|||||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||||
|
github.com/go-telegram/bot v1.2.1 h1:FkrixLCtMtPUQAN4plXdNElbhkdXkx2p68YPXKBruDg=
|
||||||
|
github.com/go-telegram/bot v1.2.1/go.mod h1:i2TRs7fXWIeaceF3z7KzsMt/he0TwkVC680mvdTFYeM=
|
||||||
github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM=
|
github.com/gofiber/fiber/v2 v2.52.4 h1:P+T+4iK7VaqUsq2PALYEfBBo6bJZ4q3FP8cZ84EggTM=
|
||||||
github.com/gofiber/fiber/v2 v2.52.4/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
github.com/gofiber/fiber/v2 v2.52.4/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ=
|
||||||
github.com/gofiber/fiber/v3 v3.0.0-20240405062939-c8c51ee78331 h1:kDxTNPKMIRz8q28+tJHL2p87Cjtmkfn/OsLfastmpaY=
|
github.com/gofiber/fiber/v3 v3.0.0-20240405062939-c8c51ee78331 h1:kDxTNPKMIRz8q28+tJHL2p87Cjtmkfn/OsLfastmpaY=
|
||||||
|
|||||||
Reference in New Issue
Block a user