From bcc9cb86ba37f86e48ebf6e295ef4d530224a6be Mon Sep 17 00:00:00 2001 From: Amrit Singh Date: Tue, 28 Jan 2025 23:51:21 +0530 Subject: [PATCH 1/9] Adding Kit interface in response to https://github.com/tmc/langchaingo/issues/1103 --- tools/tool.go | 16 +++++++++++++++- tools/tool_test.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 tools/tool_test.go diff --git a/tools/tool.go b/tools/tool.go index 4cfca7594..c76f7f398 100644 --- a/tools/tool.go +++ b/tools/tool.go @@ -1,6 +1,9 @@ package tools -import "context" +import ( + "context" + "fmt" +) // Tool is a tool for the llm agent to interact with different applications. type Tool interface { @@ -8,3 +11,14 @@ type Tool interface { Description() string Call(ctx context.Context, input string) (string, error) } + +type Kit []Tool + +func (tb *Kit) UseTool(ctx context.Context, toolName string, toolArgs string) (string, error) { + for _, tool := range *tb { + if tool.Name() == toolName { + return tool.Call(ctx, toolArgs) + } + } + return "", fmt.Errorf("invalid tool %v", toolName) +} diff --git a/tools/tool_test.go b/tools/tool_test.go new file mode 100644 index 000000000..21f4cbbef --- /dev/null +++ b/tools/tool_test.go @@ -0,0 +1,44 @@ +package tools + +import ( + "context" + "testing" +) + +type SomeTool struct { +} + +func (st *SomeTool) Name() string { + return "An awesome tool" +} +func (st *SomeTool) Description() string { + return "This tool is awesome" +} +func (st *SomeTool) Call(ctx context.Context, input string) (string, error) { + return "test", nil +} +func TestTool(t *testing.T) { + + t.Run("Tool Exists in Kit", func(t *testing.T) { + + kit := Kit{ + &SomeTool{}, + } + _, err := kit.UseTool(context.Background(), "An awesome tool", "test") + if err != nil { + t.Errorf("Error using tool: %v", err) + } + }) + + t.Run("Tool Does Not Exist in Kit", func(t *testing.T) { + + kit := Kit{ + &SomeTool{}, + } + _, err := kit.UseTool(context.Background(), "A tool that does not exist", "test") + if err == nil { + t.Errorf("Expected error, got nil") + } + }) + +} From 571471b1565069b0da78bc72ce893c82efc1e59d Mon Sep 17 00:00:00 2001 From: Amrit Singh Date: Wed, 29 Jan 2025 00:10:53 +0530 Subject: [PATCH 2/9] fixing Linting errors from CI --- tools/tool_test.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/tool_test.go b/tools/tool_test.go index 21f4cbbef..225f3a7c2 100644 --- a/tools/tool_test.go +++ b/tools/tool_test.go @@ -15,12 +15,13 @@ func (st *SomeTool) Description() string { return "This tool is awesome" } func (st *SomeTool) Call(ctx context.Context, input string) (string, error) { + if ctx.Err() != nil { + return "", ctx.Err() + } return "test", nil } func TestTool(t *testing.T) { - t.Run("Tool Exists in Kit", func(t *testing.T) { - kit := Kit{ &SomeTool{}, } @@ -29,9 +30,7 @@ func TestTool(t *testing.T) { t.Errorf("Error using tool: %v", err) } }) - t.Run("Tool Does Not Exist in Kit", func(t *testing.T) { - kit := Kit{ &SomeTool{}, } @@ -40,5 +39,4 @@ func TestTool(t *testing.T) { t.Errorf("Expected error, got nil") } }) - } From 1853330b5d01fca2256a1eb8f0b11013662d1b0d Mon Sep 17 00:00:00 2001 From: Amrit Singh Date: Wed, 29 Jan 2025 00:13:41 +0530 Subject: [PATCH 3/9] fixing Linting errors from CI --- tools/tool_test.go | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/tools/tool_test.go b/tools/tool_test.go index 225f3a7c2..f80552de9 100644 --- a/tools/tool_test.go +++ b/tools/tool_test.go @@ -1,27 +1,19 @@ package tools - -import ( - "context" - "testing" -) - -type SomeTool struct { -} - -func (st *SomeTool) Name() string { - return "An awesome tool" -} -func (st *SomeTool) Description() string { - return "This tool is awesome" -} -func (st *SomeTool) Call(ctx context.Context, input string) (string, error) { +// The 'input' parameter in the Call method is unused, so we will rename it to '_' +// to indicate that it is intentionally ignored. +func (st *SomeTool) Call(ctx context.Context, _ string) (string, error) { if ctx.Err() != nil { return "", ctx.Err() } return "test", nil } + +// Additionally, we will modify the TestTool function to run tests in parallel func TestTool(t *testing.T) { + t.Parallel() // Call to method parallel + t.Run("Tool Exists in Kit", func(t *testing.T) { + t.Parallel() // Call to method parallel in the test run kit := Kit{ &SomeTool{}, } @@ -30,7 +22,9 @@ func TestTool(t *testing.T) { t.Errorf("Error using tool: %v", err) } }) + t.Run("Tool Does Not Exist in Kit", func(t *testing.T) { + t.Parallel() // Call to method parallel in the test run kit := Kit{ &SomeTool{}, } @@ -39,4 +33,3 @@ func TestTool(t *testing.T) { t.Errorf("Expected error, got nil") } }) -} From 07a4dfbd334155c47ffacb3eb997fab3ce565383 Mon Sep 17 00:00:00 2001 From: Amrit Singh Date: Wed, 29 Jan 2025 00:17:41 +0530 Subject: [PATCH 4/9] fixing Linting errors from CI --- tools/tool_test.go | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/tools/tool_test.go b/tools/tool_test.go index f80552de9..572a14303 100644 --- a/tools/tool_test.go +++ b/tools/tool_test.go @@ -1,19 +1,28 @@ package tools -// The 'input' parameter in the Call method is unused, so we will rename it to '_' -// to indicate that it is intentionally ignored. + +import ( + "context" + "testing" +) + +type SomeTool struct { +} + +func (st *SomeTool) Name() string { + return "An awesome tool" +} +func (st *SomeTool) Description() string { + return "This tool is awesome" +} func (st *SomeTool) Call(ctx context.Context, _ string) (string, error) { if ctx.Err() != nil { return "", ctx.Err() } return "test", nil } - -// Additionally, we will modify the TestTool function to run tests in parallel func TestTool(t *testing.T) { - t.Parallel() // Call to method parallel - t.Run("Tool Exists in Kit", func(t *testing.T) { - t.Parallel() // Call to method parallel in the test run + t.Parallel() kit := Kit{ &SomeTool{}, } @@ -22,9 +31,8 @@ func TestTool(t *testing.T) { t.Errorf("Error using tool: %v", err) } }) - t.Run("Tool Does Not Exist in Kit", func(t *testing.T) { - t.Parallel() // Call to method parallel in the test run + t.Parallel() kit := Kit{ &SomeTool{}, } @@ -33,3 +41,4 @@ func TestTool(t *testing.T) { t.Errorf("Expected error, got nil") } }) +} From 562bc8264c7b7d2b0d40b458894fd7c7a4d2c8a4 Mon Sep 17 00:00:00 2001 From: Amrit Singh Date: Wed, 29 Jan 2025 00:19:47 +0530 Subject: [PATCH 5/9] fixing linter: run tests in parallel --- tools/tool_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/tool_test.go b/tools/tool_test.go index 572a14303..782cad621 100644 --- a/tools/tool_test.go +++ b/tools/tool_test.go @@ -21,6 +21,7 @@ func (st *SomeTool) Call(ctx context.Context, _ string) (string, error) { return "test", nil } func TestTool(t *testing.T) { + t.Parallel() t.Run("Tool Exists in Kit", func(t *testing.T) { t.Parallel() kit := Kit{ From b0d2e9c06dc83444952db924f71777ca5bf59f01 Mon Sep 17 00:00:00 2001 From: Amrit Singh Date: Wed, 29 Jan 2025 00:22:07 +0530 Subject: [PATCH 6/9] fixing linter: gofumt the type Sometool --- tools/tool_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/tool_test.go b/tools/tool_test.go index 782cad621..0e5e0959d 100644 --- a/tools/tool_test.go +++ b/tools/tool_test.go @@ -5,8 +5,7 @@ import ( "testing" ) -type SomeTool struct { -} +type SomeTool struct{} func (st *SomeTool) Name() string { return "An awesome tool" From a957258be4093404aa6fbef92ceb8e013169570e Mon Sep 17 00:00:00 2001 From: Amrit Singh Date: Wed, 29 Jan 2025 00:31:46 +0530 Subject: [PATCH 7/9] fixing linter: gofumt the type Sometool --- .../anthropic-tool-call-example.go | 1 - .../llamafile_completion_example.go | 3 --- examples/maritaca-example/maritaca-chat-example.go | 2 -- .../mistral-embedding-example/mistral-embedding-example.go | 1 - .../openai-gpt4o-mutil-content.go | 3 ++- examples/openai-jsonformat-example/openai-jsonformat.go | 3 ++- .../pinecone_vectorstore_example.go | 6 +++--- examples/zep-memory-chain-example/main.go | 3 ++- tools/tool_test.go | 3 +++ 9 files changed, 12 insertions(+), 13 deletions(-) diff --git a/examples/anthropic-tool-call-example/anthropic-tool-call-example.go b/examples/anthropic-tool-call-example/anthropic-tool-call-example.go index 72e53f0f8..9a1e455d7 100644 --- a/examples/anthropic-tool-call-example/anthropic-tool-call-example.go +++ b/examples/anthropic-tool-call-example/anthropic-tool-call-example.go @@ -87,7 +87,6 @@ func main() { log.Fatal(err) } fmt.Println(resp.Choices[0].Content) - } // executeToolCalls executes the tool calls in the response and returns the diff --git a/examples/llamafile-completion-example/llamafile_completion_example.go b/examples/llamafile-completion-example/llamafile_completion_example.go index 194a01a98..4ef7c3806 100644 --- a/examples/llamafile-completion-example/llamafile_completion_example.go +++ b/examples/llamafile-completion-example/llamafile_completion_example.go @@ -9,13 +9,11 @@ import ( ) func main() { - options := []llamafile.Option{ llamafile.WithEmbeddingSize(2048), llamafile.WithTemperature(0.8), } llm, err := llamafile.New(options...) - if err != nil { panic(err) } @@ -35,7 +33,6 @@ func main() { fmt.Print(string(chunk)) return nil })) - if err != nil { panic(err) } diff --git a/examples/maritaca-example/maritaca-chat-example.go b/examples/maritaca-example/maritaca-chat-example.go index 3b4628257..2c0854e9a 100644 --- a/examples/maritaca-example/maritaca-chat-example.go +++ b/examples/maritaca-example/maritaca-chat-example.go @@ -16,7 +16,6 @@ func main() { maritaca.WithModel("sabia-2-medium"), } llm, err := maritaca.New(opts...) - if err != nil { panic(err) } @@ -28,5 +27,4 @@ func main() { panic(err) } fmt.Println(resp) - } diff --git a/examples/mistral-embedding-example/mistral-embedding-example.go b/examples/mistral-embedding-example/mistral-embedding-example.go index a85381c0b..9a427baf1 100644 --- a/examples/mistral-embedding-example/mistral-embedding-example.go +++ b/examples/mistral-embedding-example/mistral-embedding-example.go @@ -24,7 +24,6 @@ func main() { } e, err := embeddings.NewEmbedder(model) - if err != nil { panic(err) } diff --git a/examples/openai-gpt4o-mutil-content/openai-gpt4o-mutil-content.go b/examples/openai-gpt4o-mutil-content/openai-gpt4o-mutil-content.go index 1207a326d..5e47ab527 100644 --- a/examples/openai-gpt4o-mutil-content/openai-gpt4o-mutil-content.go +++ b/examples/openai-gpt4o-mutil-content/openai-gpt4o-mutil-content.go @@ -3,9 +3,10 @@ package main import ( "context" "fmt" + "log" + "github.com/tmc/langchaingo/llms" "github.com/tmc/langchaingo/llms/openai" - "log" ) func main() { diff --git a/examples/openai-jsonformat-example/openai-jsonformat.go b/examples/openai-jsonformat-example/openai-jsonformat.go index e02272268..dc34345ae 100644 --- a/examples/openai-jsonformat-example/openai-jsonformat.go +++ b/examples/openai-jsonformat-example/openai-jsonformat.go @@ -2,9 +2,10 @@ package main import ( "context" + "log" + "github.com/tmc/langchaingo/llms" "github.com/tmc/langchaingo/llms/openai" - "log" ) type User struct { diff --git a/examples/pinecone-vectorstore-example/pinecone_vectorstore_example.go b/examples/pinecone-vectorstore-example/pinecone_vectorstore_example.go index 1b1be6c33..d64df8667 100644 --- a/examples/pinecone-vectorstore-example/pinecone_vectorstore_example.go +++ b/examples/pinecone-vectorstore-example/pinecone_vectorstore_example.go @@ -15,10 +15,10 @@ import ( func main() { // Create an embeddings client using the OpenAI API. Requires environment variable OPENAI_API_KEY to be set. - - llm, err := openai.New(openai.WithEmbeddingModel("text-embedding-3-small"))// Specify your preferred embedding model + + llm, err := openai.New(openai.WithEmbeddingModel("text-embedding-3-small")) // Specify your preferred embedding model if err != nil { - log.Fatal(err) + log.Fatal(err) } e, err := embeddings.NewEmbedder(llm) diff --git a/examples/zep-memory-chain-example/main.go b/examples/zep-memory-chain-example/main.go index 6d9b1a916..c17228275 100644 --- a/examples/zep-memory-chain-example/main.go +++ b/examples/zep-memory-chain-example/main.go @@ -3,13 +3,14 @@ package main import ( "context" "fmt" + "os" + "github.com/getzep/zep-go" zepClient "github.com/getzep/zep-go/client" zepOption "github.com/getzep/zep-go/option" "github.com/tmc/langchaingo/chains" "github.com/tmc/langchaingo/llms/openai" zepLangchainMemory "github.com/tmc/langchaingo/memory/zep" - "os" ) func main() { diff --git a/tools/tool_test.go b/tools/tool_test.go index 0e5e0959d..f5362d8cb 100644 --- a/tools/tool_test.go +++ b/tools/tool_test.go @@ -10,15 +10,18 @@ type SomeTool struct{} func (st *SomeTool) Name() string { return "An awesome tool" } + func (st *SomeTool) Description() string { return "This tool is awesome" } + func (st *SomeTool) Call(ctx context.Context, _ string) (string, error) { if ctx.Err() != nil { return "", ctx.Err() } return "test", nil } + func TestTool(t *testing.T) { t.Parallel() t.Run("Tool Exists in Kit", func(t *testing.T) { From 90bd75a10583c8835dc03a5ebbe9e41e8a08741f Mon Sep 17 00:00:00 2001 From: Amrit Singh Date: Wed, 29 Jan 2025 08:53:34 +0530 Subject: [PATCH 8/9] reverting accidental change to examples --- .../anthropic-tool-call-example.go | 1 + .../llamafile_completion_example.go | 3 +++ .../maritaca-example/maritaca-chat-example.go | 2 ++ .../mistral-embedding-example.go | 1 + .../openai-gpt4o-mutil-content.go | 3 +-- .../openai-jsonformat.go | 3 +-- .../pinecone_vectorstore_example.go | 6 +++--- examples/zep-memory-chain-example/main.go | 3 +-- tools/tool.go | 16 +--------------- 9 files changed, 14 insertions(+), 24 deletions(-) diff --git a/examples/anthropic-tool-call-example/anthropic-tool-call-example.go b/examples/anthropic-tool-call-example/anthropic-tool-call-example.go index 9a1e455d7..72e53f0f8 100644 --- a/examples/anthropic-tool-call-example/anthropic-tool-call-example.go +++ b/examples/anthropic-tool-call-example/anthropic-tool-call-example.go @@ -87,6 +87,7 @@ func main() { log.Fatal(err) } fmt.Println(resp.Choices[0].Content) + } // executeToolCalls executes the tool calls in the response and returns the diff --git a/examples/llamafile-completion-example/llamafile_completion_example.go b/examples/llamafile-completion-example/llamafile_completion_example.go index 4ef7c3806..194a01a98 100644 --- a/examples/llamafile-completion-example/llamafile_completion_example.go +++ b/examples/llamafile-completion-example/llamafile_completion_example.go @@ -9,11 +9,13 @@ import ( ) func main() { + options := []llamafile.Option{ llamafile.WithEmbeddingSize(2048), llamafile.WithTemperature(0.8), } llm, err := llamafile.New(options...) + if err != nil { panic(err) } @@ -33,6 +35,7 @@ func main() { fmt.Print(string(chunk)) return nil })) + if err != nil { panic(err) } diff --git a/examples/maritaca-example/maritaca-chat-example.go b/examples/maritaca-example/maritaca-chat-example.go index 2c0854e9a..3b4628257 100644 --- a/examples/maritaca-example/maritaca-chat-example.go +++ b/examples/maritaca-example/maritaca-chat-example.go @@ -16,6 +16,7 @@ func main() { maritaca.WithModel("sabia-2-medium"), } llm, err := maritaca.New(opts...) + if err != nil { panic(err) } @@ -27,4 +28,5 @@ func main() { panic(err) } fmt.Println(resp) + } diff --git a/examples/mistral-embedding-example/mistral-embedding-example.go b/examples/mistral-embedding-example/mistral-embedding-example.go index 9a427baf1..a85381c0b 100644 --- a/examples/mistral-embedding-example/mistral-embedding-example.go +++ b/examples/mistral-embedding-example/mistral-embedding-example.go @@ -24,6 +24,7 @@ func main() { } e, err := embeddings.NewEmbedder(model) + if err != nil { panic(err) } diff --git a/examples/openai-gpt4o-mutil-content/openai-gpt4o-mutil-content.go b/examples/openai-gpt4o-mutil-content/openai-gpt4o-mutil-content.go index 5e47ab527..1207a326d 100644 --- a/examples/openai-gpt4o-mutil-content/openai-gpt4o-mutil-content.go +++ b/examples/openai-gpt4o-mutil-content/openai-gpt4o-mutil-content.go @@ -3,10 +3,9 @@ package main import ( "context" "fmt" - "log" - "github.com/tmc/langchaingo/llms" "github.com/tmc/langchaingo/llms/openai" + "log" ) func main() { diff --git a/examples/openai-jsonformat-example/openai-jsonformat.go b/examples/openai-jsonformat-example/openai-jsonformat.go index dc34345ae..e02272268 100644 --- a/examples/openai-jsonformat-example/openai-jsonformat.go +++ b/examples/openai-jsonformat-example/openai-jsonformat.go @@ -2,10 +2,9 @@ package main import ( "context" - "log" - "github.com/tmc/langchaingo/llms" "github.com/tmc/langchaingo/llms/openai" + "log" ) type User struct { diff --git a/examples/pinecone-vectorstore-example/pinecone_vectorstore_example.go b/examples/pinecone-vectorstore-example/pinecone_vectorstore_example.go index d64df8667..1b1be6c33 100644 --- a/examples/pinecone-vectorstore-example/pinecone_vectorstore_example.go +++ b/examples/pinecone-vectorstore-example/pinecone_vectorstore_example.go @@ -15,10 +15,10 @@ import ( func main() { // Create an embeddings client using the OpenAI API. Requires environment variable OPENAI_API_KEY to be set. - - llm, err := openai.New(openai.WithEmbeddingModel("text-embedding-3-small")) // Specify your preferred embedding model + + llm, err := openai.New(openai.WithEmbeddingModel("text-embedding-3-small"))// Specify your preferred embedding model if err != nil { - log.Fatal(err) + log.Fatal(err) } e, err := embeddings.NewEmbedder(llm) diff --git a/examples/zep-memory-chain-example/main.go b/examples/zep-memory-chain-example/main.go index c17228275..6d9b1a916 100644 --- a/examples/zep-memory-chain-example/main.go +++ b/examples/zep-memory-chain-example/main.go @@ -3,14 +3,13 @@ package main import ( "context" "fmt" - "os" - "github.com/getzep/zep-go" zepClient "github.com/getzep/zep-go/client" zepOption "github.com/getzep/zep-go/option" "github.com/tmc/langchaingo/chains" "github.com/tmc/langchaingo/llms/openai" zepLangchainMemory "github.com/tmc/langchaingo/memory/zep" + "os" ) func main() { diff --git a/tools/tool.go b/tools/tool.go index c76f7f398..4cfca7594 100644 --- a/tools/tool.go +++ b/tools/tool.go @@ -1,9 +1,6 @@ package tools -import ( - "context" - "fmt" -) +import "context" // Tool is a tool for the llm agent to interact with different applications. type Tool interface { @@ -11,14 +8,3 @@ type Tool interface { Description() string Call(ctx context.Context, input string) (string, error) } - -type Kit []Tool - -func (tb *Kit) UseTool(ctx context.Context, toolName string, toolArgs string) (string, error) { - for _, tool := range *tb { - if tool.Name() == toolName { - return tool.Call(ctx, toolArgs) - } - } - return "", fmt.Errorf("invalid tool %v", toolName) -} From f6745902137242139a371caf6e3c7438eceb5677 Mon Sep 17 00:00:00 2001 From: Amrit Singh Date: Wed, 29 Jan 2025 08:56:04 +0530 Subject: [PATCH 9/9] reverting accidental change to examples --- tools/tool.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tools/tool.go b/tools/tool.go index 4cfca7594..c76f7f398 100644 --- a/tools/tool.go +++ b/tools/tool.go @@ -1,6 +1,9 @@ package tools -import "context" +import ( + "context" + "fmt" +) // Tool is a tool for the llm agent to interact with different applications. type Tool interface { @@ -8,3 +11,14 @@ type Tool interface { Description() string Call(ctx context.Context, input string) (string, error) } + +type Kit []Tool + +func (tb *Kit) UseTool(ctx context.Context, toolName string, toolArgs string) (string, error) { + for _, tool := range *tb { + if tool.Name() == toolName { + return tool.Call(ctx, toolArgs) + } + } + return "", fmt.Errorf("invalid tool %v", toolName) +}