Repository: tmc/langchaingo
Pull request #195 (2023-07-15 02:04:50)

outputparser: Add BooleanParser
References:
- [langchain (python) boolean output parser](https://github.com/hwchase17/langchain/blob/master/langchain/output_parsers/boolean.py).

Changes:
- Adds functionality `outputparser` `BooleanParser`.

### PR Checklist

- [x] Read the [Contributing documentation](https://github.com/tmc/langchaingo/blob/main/CONTRIBUTING.md).
- [x] Read the [Code of conduct documentation](https://github.com/tmc/langchaingo/blob/main/CODE_OF_CONDUCT.md).
- [x] Name your Pull Request title clearly, concisely, and prefixed with the name of the primarily affected package you changed according to [Good commit messages](https://go.dev/doc/contribute#commit_messages) (such as `memory: add interfaces for X, Y` or `util: add whizzbang helpers`).
- [x] Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
- [x] Provide a description in this PR that addresses **what** the PR is solving, or reference the issue that it solves (e.g. `Fixes #123`).
- [x] Describes the source of new concepts.
- [x] References existing implementations as appropriate.
- [x] Contains test coverage for new functions.
- [x] Passes all [`golangci-lint`](https://golangci-lint.run/) checks.



Patch:
diff --git a/docs/parity_matrix.md b/docs/parity_matrix.md
index 2c0df583..54358604 100644
--- a/docs/parity_matrix.md
+++ b/docs/parity_matrix.md
@@ -80,7 +80,7 @@ Please note that this page lists the current state of the LangChain Go project,
 | ----------------------------| ------ |
 | Simple                      | ✅     |
 | Structured                  | ✅     |
-| Boolean                     | ❌     |
+| Boolean                     | ✅     |
 | Combining Parsers           | ✅     |
 | Regex                       | ✅     |
 | Regex Dictionary            | ❌     |
diff --git a/outputparser/boolean_parser.go b/outputparser/boolean_parser.go
new file mode 100644
index 00000000..bcf2e887
--- /dev/null
+++ b/outputparser/boolean_parser.go
@@ -0,0 +1,67 @@
+package outputparser
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/tmc/langchaingo/schema"
+	"golang.org/x/exp/slices"
+)
+
+// BooleanParser is an output parser used to parse the output of an llm as a boolean.
+type BooleanParser struct {
+	TrueStr  string
+	FalseStr string
+}
+
+// NewBooleanParser returns a new BooleanParser.
+func NewBooleanParser() BooleanParser {
+	return BooleanParser{
+		TrueStr:  "YES",
+		FalseStr: "NO",
+	}
+}
+
+// Statically assert that BooleanParser implements the OutputParser interface.
+var _ schema.OutputParser[any] = BooleanParser{}
+
+// GetFormatInstructions returns instructions on the expected output format.
+func (p BooleanParser) GetFormatInstructions() string {
+	return "Your output should be a boolean. e.g.:\n `true` or `false`"
+}
+
+func (p BooleanParser) parse(text string) (bool, error) {
+	text = normalize(text)
+	booleanStrings := []string{p.TrueStr, p.FalseStr}
+
+	if !slices.Contains(booleanStrings, text) {
+		return false, ParseError{
+			Text:   text,
+			Reason: fmt.Sprintf("Expected output to be either '%s' or '%s', received %s", p.TrueStr, p.FalseStr, text),
+		}
+	}
+
+	return text == p.TrueStr, nil
+}
+
+func normalize(text string) string {
+	text = strings.TrimSpace(text)
+	text = strings.ToUpper(text)
+
+	return text
+}
+
+// Parse parses the output of an llm into a map of strings.
+func (p BooleanParser) Parse(text string) (any, error) {
+	return p.parse(text)
+}
+
+// ParseWithPrompt does the same as Parse.
+func (p BooleanParser) ParseWithPrompt(text string, _ schema.PromptValue) (any, error) {
+	return p.parse(text)
+}
+
+// Type returns the type of the parser.
+func (p BooleanParser) Type() string {
+	return "boolean_parser"
+}
diff --git a/outputparser/doc.go b/outputparser/doc.go
index cc6d9385..1a7f9703 100644
--- a/outputparser/doc.go
+++ b/outputparser/doc.go
@@ -4,6 +4,7 @@ unstructured data from language models (LLMs).
 
 The outputparser package includes the following parsers:
 
+  - BooleanParser: a parser that returns a boolean value based on string values assigned to true and false.
   - Simple: a basic parser that returns the raw text as-is without any processing.
   - Structured: a parser that expects a JSON-formatted response and returns it as
     a map[string]string while validating against a provided schema.


Test patch:
diff --git a/outputparser/boolean_parser_test.go b/outputparser/boolean_parser_test.go
new file mode 100644
index 00000000..9ab92c66
--- /dev/null
+++ b/outputparser/boolean_parser_test.go
@@ -0,0 +1,48 @@
+package outputparser_test
+
+import (
+	"testing"
+
+	"github.com/tmc/langchaingo/outputparser"
+)
+
+func TestBooleanParser(t *testing.T) {
+	t.Parallel()
+
+	testCases := []struct {
+		input    string
+		err      error
+		expected bool
+	}{
+		{
+			input:    "Yes",
+			expected: true,
+		},
+		{
+			input:    "NO",
+			expected: false,
+		},
+		{
+			input:    "YESNO",
+			expected: false,
+		},
+		{
+			input:    "ok",
+			err:      outputparser.ParseError{},
+			expected: false,
+		},
+	}
+
+	for _, tc := range testCases {
+		parser := outputparser.NewBooleanParser()
+
+		actual, err := parser.Parse(tc.input)
+		if tc.err != nil && err == nil {
+			t.Errorf("Expected error %v, got nil", tc.err)
+		}
+
+		if actual != tc.expected {
+			t.Errorf("Expected %v, got %v", tc.expected, actual)
+		}
+	}
+}