Skip to content

Commit a78430d

Browse files
committed
refactor: added hello world tools
1 parent af77cdd commit a78430d

5 files changed

Lines changed: 51 additions & 20 deletions

File tree

agents/agents.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package agents
88

99
import (
1010
"context"
11+
"encoding/json"
1112
"fmt"
1213

1314
"github.com/bit8bytes/beago/inputs/roles"
@@ -20,18 +21,17 @@ import (
2021
// FinalAnswer being non-empty signals the agent is done; otherwise Action and
2122
// ActionInput describe the next tool to call.
2223
type response struct {
23-
Thought string `json:"thought"`
24-
Action string `json:"action"`
25-
ActionInput string `json:"action_input"`
26-
FinalAnswer string `json:"final_answer"`
24+
Thought string `json:"thought"`
25+
Action string `json:"action"`
26+
ActionInput json.RawMessage `json:"action_input"`
27+
FinalAnswer string `json:"final_answer"`
2728
}
2829

2930
// Action is the domain representation of a tool call, extracted from a
30-
// response. Name matches the tool's Name() and Input is passed verbatim to
31-
// Tool.Execute.
31+
// response. Name matches the tool's Name() and Input is passed to Tool.Execute.
3232
type Action struct {
3333
Name string
34-
Input string
34+
Input json.RawMessage
3535
}
3636

3737
type llm interface {

agents/react.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ func buildReActPrompt(tls map[string]tools.Tool, jsonInstructions string) []llms
3535
var toolDescriptions strings.Builder
3636
for _, t := range tls {
3737
fmt.Fprintf(&toolDescriptions, "- %s: %s\n", t.Name(), t.Description())
38+
for _, p := range t.Parameters() {
39+
req := "optional"
40+
if p.Required {
41+
req = "required"
42+
}
43+
fmt.Fprintf(&toolDescriptions, " - %s (%s): %s\n", p.Name, req, p.Description)
44+
}
3845
}
3946

4047
wd, _ := os.Getwd()
@@ -55,10 +62,10 @@ Available tools:
5562
Respond with a JSON object on each turn with these fields:
5663
- "thought": your reasoning about what to do next
5764
- "action": the exact tool name to call (empty string when giving final answer)
58-
- "action_input": the input to pass to the tool (empty string when giving final answer)
65+
- "action_input": a JSON object whose keys are the tool's parameter names (empty object {} when giving final answer)
5966
- "final_answer": your final answer to the user — MUST be non-empty when you are done; empty string ONLY when calling a tool
6067
61-
When you have enough information to answer, set "action" and "action_input" to "" and put a detailed answer based on your observations — MUST be non-empty when done; be thorough and include all relevant findings.
68+
When you have enough information to answer, set "action" to "" and "action_input" to {} and put a detailed answer based on your observations — MUST be non-empty when done; be thorough and include all relevant findings.
6269
6370
Think step by step. Do not hallucinate.`, wd, toolDescriptions.String(), jsonInstructions),
6471
},

examples/agents/hello/main.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ func main() {
2727
Format: ollama.JSON,
2828
})
2929

30-
// These tools are specifically designed for Golang.
31-
tools := []tools.Tool{
32-
&tools.HelloWorldTool{},
33-
}
30+
tools := []tools.Tool{&tools.HelloWorldTool{}}
3431

3532
agent, err := agents.NewReAct(ctx, model, tools, storage)
3633
if err != nil {

tools/helloworld.go

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package tools
22

3-
import "context"
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
)
48

59
type HelloWorldTool struct{}
610

@@ -9,9 +13,21 @@ func (t *HelloWorldTool) Name() string {
913
}
1014

1115
func (t *HelloWorldTool) Description() string {
12-
return "Returns a hello greeting for the given name. Input: a name string."
16+
return "Returns a hello greeting for the given name."
1317
}
1418

15-
func (t *HelloWorldTool) Execute(_ context.Context, input string) (string, error) {
16-
return "Hello, " + input + "!", nil
19+
func (t *HelloWorldTool) Parameters() []Parameter {
20+
return []Parameter{
21+
{Name: "name", Description: "The name to greet", Required: true},
22+
}
23+
}
24+
25+
func (t *HelloWorldTool) Execute(_ context.Context, params json.RawMessage) (string, error) {
26+
var input struct {
27+
Name string `json:"name"`
28+
}
29+
if err := json.Unmarshal(params, &input); err != nil {
30+
return "", fmt.Errorf("helloWorld: invalid params: %w", err)
31+
}
32+
return "Hello, " + input.Name + "!", nil
1733
}

tools/tools.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,23 @@
22
// implementations that agents can use to interact with the outside world.
33
package tools
44

5-
import "context"
5+
import (
6+
"context"
7+
"encoding/json"
8+
)
9+
10+
// Parameter describes a single input field a tool accepts.
11+
type Parameter struct {
12+
Name string
13+
Description string
14+
Required bool
15+
}
616

717
// Tool represents an action the agent can perform.
8-
// Each tool must provide a name, description, and execution logic.
18+
// Each tool must provide a name, description, parameter schema, and execution logic.
919
type Tool interface {
1020
Name() string
1121
Description() string
12-
Execute(ctx context.Context, input string) (string, error)
22+
Parameters() []Parameter
23+
Execute(ctx context.Context, params json.RawMessage) (string, error)
1324
}

0 commit comments

Comments
 (0)