Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into merge-upstream-0324
Browse files Browse the repository at this point in the history
  • Loading branch information
Ayoub Chouak committed Mar 21, 2024
2 parents 5b3f8d4 + 60fa95d commit a1fdad3
Show file tree
Hide file tree
Showing 456 changed files with 23,518 additions and 3,891 deletions.
2 changes: 2 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# These are supported funding model platforms
github: tmc
8 changes: 7 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: ci

on:
push:
branches:
- main
pull_request:
branches:
- main
Expand All @@ -18,9 +20,10 @@ jobs:
cache: false
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@v3.6.0
uses: golangci/golangci-lint-action@v3.7.0
with:
args: --timeout=4m
version: v1.55.1
build-examples:
runs-on: ubuntu-latest
steps:
Expand All @@ -41,4 +44,7 @@ jobs:
- name: Build
run: go build -v ./...
- name: Test
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
GENAI_API_KEY: ${{ secrets.GENAI_API_KEY }}
run: go test -v ./...
49 changes: 49 additions & 0 deletions .github/workflows/publish-docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Deploy to GitHub Pages

on:
push:
branches:
- main

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: "pages"
cancel-in-progress: false

jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
cache: yarn
cache-dependency-path: 'docs/package-lock.json'

- name: Install dependencies
working-directory: docs
run: yarn install --frozen-lockfile
- name: Build website
working-directory: docs
run: yarn build

- name: Setup Pages
uses: actions/configure-pages@v3
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
# Upload entire repository
path: 'docs/build'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ go.work.sum

# Test outputs
coverage.out
cover.cov

# macOS Specific
.DS_Store
Expand All @@ -14,3 +15,6 @@ coverage.out
# dev
.env
vendor/*

embeddings/cybertron/models/*
examples/cybertron-embedding-example/models/*
5 changes: 5 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,20 @@ linters:
- tagliatelle # As we're dealing with third parties we must accept snake case.
- wsl # We don't agree with wsl's style rules
- exhaustruct
- lll
- varnamelen
- nlreturn
- gomnd
- goerr113
- wrapcheck # TODO: we should probably enable this one (at least for new code).
- testpackage
- nolintlint # see https://github.com/golangci/golangci-lint/issues/3228.
- depguard # disabling temporarily
- ireturn # disabling temporarily

linters-settings:
cyclop:
max-complexity: 12
funlen:
lines: 90
depguard:
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ All types of contributions are encouraged and valued. See the [Table of Contents
## Code of Conduct

This project and everyone participating in it is governed by the
[langchaingo Code of Conduct](/CODE_OF_CONDUCT.md).
[langchaingo Code of Conduct](CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable behavior
to <[email protected]>.

Expand Down
19 changes: 18 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ test:
go test ./...

.PHONY: lint
lint:
lint: lint-deps
golangci-lint run --color=always --sort-results ./...

.PHONY: lint-exp
Expand All @@ -22,6 +22,18 @@ lint-fix:
lint-all:
golangci-lint run --color=always --sort-results ./...

.PHONY: lint-deps
lint-deps:
@command -v golangci-lint >/dev/null 2>&1 || { \
echo >&2 "golangci-lint not found. Installing..."; \
go install github.com/golangci/golangci-lint/cmd/[email protected]; \
}

.PHONY: docs
docs:
@echo "Generating documentation..."
$(MAKE) -C docs build

.PHONY: test-race
test-race:
go run test -race ./...
Expand All @@ -45,3 +57,8 @@ clean-lint-cache:
build-examples:
for example in $(shell find ./examples -mindepth 1 -maxdepth 1 -type d); do \
(cd $$example; echo Build $$example; go mod tidy; go build -o /dev/null) || exit 1; done

.PHONY: add-go-work
add-go-work:
go work init .
go work use -r .
47 changes: 28 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@

[![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/tmc/langchaingo)
[![scorecard](https://goreportcard.com/badge/github.com/tmc/langchaingo)](https://goreportcard.com/report/github.com/tmc/langchaingo)
[![](https://dcbadge.vercel.app/api/server/2NgDkQDjpQ?compact=true&style=flat)](https://discord.gg/2NgDkQDjpQ)
[![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/tmc/langchaingo)
[<img src="https://github.com/codespaces/badge.svg" title="Open in Github Codespace" width="150" height="20">](https://codespaces.new/tmc/langchaingo)

⚡ Building applications with LLMs through composability ⚡
⚡ Building applications with LLMs through composability, with Go!

## 🤔 What is this?

This is the Go language implementation of LangChain.
This is the Go language implementation of [LangChain](https://github.com/langchain-ai/langchain).

## 📖 Documentation

- [Documentation Site](https://tmc.github.io/langchaingo/docs/)
- [API Reference](https://pkg.go.dev/github.com/tmc/langchaingo)


## 🎉 Examples

See [./examples](./examples) for example usage.
Expand All @@ -21,35 +26,39 @@ See [./examples](./examples) for example usage.
package main

import (
"context"
"log"
"context"
"fmt"
"log"

"github.com/tmc/langchaingo/llms/openai"
"github.com/tmc/langchaingo/llms"
"github.com/tmc/langchaingo/llms/openai"
)

func main() {
llm, err := openai.New()
if err != nil {
log.Fatal(err)
}
prompt := "What would be a good company name for a company that makes colorful socks?"
completion, err := llm.Call(context.Background(), prompt)
if err != nil {
log.Fatal(err)
}
log.Println(completion)
ctx := context.Background()
llm, err := openai.New()
if err != nil {
log.Fatal(err)
}
prompt := "What would be a good company name for a company that makes colorful socks?"
completion, err := llms.GenerateFromSinglePrompt(ctx, llm, prompt)
if err != nil {
log.Fatal(err)
}
fmt.Println(completion)
}
```

```shell
$ go run .

Socktastic!
Socktastic
```

# Resources

Here are some links to blog posts and articles on using Langchain Go:

- [Creating a simple ChatGPT clone with Go](https://sausheong.com/creating-a-simple-chatgpt-clone-with-go-c40b4bec9267?sk=53a2bcf4ce3b0cfae1a4c26897c0deb0)
- [Creating a ChatGPT Clone that Runs on Your Laptop with Go](https://sausheong.com/creating-a-chatgpt-clone-that-runs-on-your-laptop-with-go-bf9d41f1cf88?sk=05dc67b60fdac6effb1aca84dd2d654e)
- [Using Gemini models in Go with LangChainGo](https://eli.thegreenplace.net/2024/using-gemini-models-in-go-with-langchaingo/) - Jan 2024
- [Using Ollama with LangChainGo](https://eli.thegreenplace.net/2023/using-ollama-with-langchaingo/) - Nov 2023
- [Creating a simple ChatGPT clone with Go](https://sausheong.com/creating-a-simple-chatgpt-clone-with-go-c40b4bec9267?sk=53a2bcf4ce3b0cfae1a4c26897c0deb0) - Aug 2023
- [Creating a ChatGPT Clone that Runs on Your Laptop with Go](https://sausheong.com/creating-a-chatgpt-clone-that-runs-on-your-laptop-with-go-bf9d41f1cf88?sk=05dc67b60fdac6effb1aca84dd2d654e) - Aug 2023
2 changes: 1 addition & 1 deletion agents/agents.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

// Agent is the interface all agents must implement.
type Agent interface {
// Given an input and previous steps decide what to do next. Returns
// Plan Given an input and previous steps decide what to do next. Returns
// either actions or a finish.
Plan(ctx context.Context, intermediateSteps []schema.AgentStep, inputs map[string]string) ([]schema.AgentAction, *schema.AgentFinish, error) //nolint:lll
GetInputKeys() []string
Expand Down
60 changes: 53 additions & 7 deletions agents/conversational.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package agents

import (
"context"
_ "embed"
"fmt"
"regexp"
"strings"

"github.com/tmc/langchaingo/callbacks"
"github.com/tmc/langchaingo/chains"
"github.com/tmc/langchaingo/llms"
"github.com/tmc/langchaingo/prompts"
"github.com/tmc/langchaingo/schema"
"github.com/tmc/langchaingo/tools"
)
Expand All @@ -25,26 +28,33 @@ const (
// able to chat with the user as well.
type ConversationalAgent struct {
// Chain is the chain used to call with the values. The chain should have an
// input called "agent_scratchpad" for the agent to put it's thoughts in.
// input called "agent_scratchpad" for the agent to put its thoughts in.
Chain chains.Chain
// Tools is a list of the tools the agent can use.
Tools []tools.Tool
// Output key is the key where the final output is placed.
OutputKey string
// CallbacksHandler is the handler for callbacks.
CallbacksHandler callbacks.Handler
}

var _ Agent = (*ConversationalAgent)(nil)

func NewConversationalAgent(llm llms.LanguageModel, tools []tools.Tool, opts ...CreationOption) *ConversationalAgent {
func NewConversationalAgent(llm llms.Model, tools []tools.Tool, opts ...Option) *ConversationalAgent {
options := conversationalDefaultOptions()
for _, opt := range opts {
opt(&options)
}

return &ConversationalAgent{
Chain: chains.NewLLMChain(llm, options.getConversationalPrompt(tools)),
Tools: tools,
OutputKey: options.outputKey,
Chain: chains.NewLLMChain(
llm,
options.getConversationalPrompt(tools),
chains.WithCallback(options.callbacksHandler),
),
Tools: tools,
OutputKey: options.outputKey,
CallbacksHandler: options.callbacksHandler,
}
}

Expand All @@ -61,11 +71,21 @@ func (a *ConversationalAgent) Plan(

fullInputs["agent_scratchpad"] = constructScratchPad(intermediateSteps)

var stream func(ctx context.Context, chunk []byte) error

if a.CallbacksHandler != nil {
stream = func(ctx context.Context, chunk []byte) error {
a.CallbacksHandler.HandleStreamingFunc(ctx, chunk)
return nil
}
}

output, err := chains.Predict(
ctx,
a.Chain,
fullInputs,
chains.WithStopWords([]string{"\nObservation:", "\n\tObservation:"}),
chains.WithStreamingFunc(stream),
)
if err != nil {
return nil, nil, err
Expand Down Expand Up @@ -110,12 +130,14 @@ func (a *ConversationalAgent) parseOutput(output string) ([]schema.AgentAction,
if strings.Contains(output, _conversationalFinalAnswerAction) {
splits := strings.Split(output, _conversationalFinalAnswerAction)

return nil, &schema.AgentFinish{
finishAction := &schema.AgentFinish{
ReturnValues: map[string]any{
a.OutputKey: splits[len(splits)-1],
},
Log: output,
}, nil
}

return nil, finishAction, nil
}

r := regexp.MustCompile(`Action: (.*?)[\n]*Action Input: (.*)`)
Expand All @@ -128,3 +150,27 @@ func (a *ConversationalAgent) parseOutput(output string) ([]schema.AgentAction,
{Tool: strings.TrimSpace(matches[1]), ToolInput: strings.TrimSpace(matches[2]), Log: output},
}, nil, nil
}

//go:embed prompts/conversational_prefix.txt
var _defaultConversationalPrefix string //nolint:gochecknoglobals

//go:embed prompts/conversational_format_instructions.txt
var _defaultConversationalFormatInstructions string //nolint:gochecknoglobals

//go:embed prompts/conversational_suffix.txt
var _defaultConversationalSuffix string //nolint:gochecknoglobals

func createConversationalPrompt(tools []tools.Tool, prefix, instructions, suffix string) prompts.PromptTemplate {
template := strings.Join([]string{prefix, instructions, suffix}, "\n\n")

return prompts.PromptTemplate{
Template: template,
TemplateFormat: prompts.TemplateFormatGoTemplate,
InputVariables: []string{"input", "agent_scratchpad"},
PartialVariables: map[string]any{
"tool_names": toolNames(tools),
"tool_descriptions": toolDescriptions(tools),
"history": "",
},
}
}
Loading

0 comments on commit a1fdad3

Please sign in to comment.