Skip to content

Commit

Permalink
Merge branch 'main' into aws-concurrency-beyond-batch
Browse files Browse the repository at this point in the history
  • Loading branch information
yaron2 authored Oct 15, 2024
2 parents 1614b51 + 1cbedb3 commit 98b880f
Show file tree
Hide file tree
Showing 29 changed files with 1,065 additions and 292 deletions.
2 changes: 1 addition & 1 deletion .build-tools/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/dapr/components-contrib/build-tools

go 1.23
go 1.23.0

require (
github.com/dapr/components-contrib v0.0.0
Expand Down
24 changes: 24 additions & 0 deletions common/authentication/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"strconv"
"time"

awsv2 "github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
v2creds "github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/feature/rds/auth"
Expand All @@ -37,6 +38,29 @@ type EnvironmentSettings struct {
Metadata map[string]string
}

func GetConfigV2(accessKey string, secretKey string, sessionToken string, region string, endpoint string) (awsv2.Config, error) {
optFns := []func(*config.LoadOptions) error{}
if region != "" {
optFns = append(optFns, config.WithRegion(region))
}

if accessKey != "" && secretKey != "" {
provider := v2creds.NewStaticCredentialsProvider(accessKey, secretKey, sessionToken)
optFns = append(optFns, config.WithCredentialsProvider(provider))
}

awsCfg, err := config.LoadDefaultConfig(context.Background(), optFns...)
if err != nil {
return awsv2.Config{}, err
}

if endpoint != "" {
awsCfg.BaseEndpoint = &endpoint
}

return awsCfg, nil
}

func GetClient(accessKey string, secretKey string, sessionToken string, region string, endpoint string) (*session.Session, error) {
awsConfig := aws.NewConfig()

Expand Down
8 changes: 2 additions & 6 deletions common/authentication/postgresql/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,10 @@ func (m *PostgresAuthMetadata) ValidateAwsIamFields() (string, string, string, e
if awsRegion == "" {
return "", "", "", errors.New("metadata property AWSRegion is missing")
}
// Note: access key and secret keys can be optional
// in the event users are leveraging the credential files for an access token.
awsAccessKey, _ := metadata.GetMetadataProperty(m.awsEnv.Metadata, "AWSAccessKey")
if awsAccessKey == "" {
return "", "", "", errors.New("metadata property AWSAccessKey is missing")
}
awsSecretKey, _ := metadata.GetMetadataProperty(m.awsEnv.Metadata, "AWSSecretKey")
if awsSecretKey == "" {
return "", "", "", errors.New("metadata property AWSSecretKey is missing")
}
return awsRegion, awsAccessKey, awsSecretKey, nil
}

Expand Down
124 changes: 124 additions & 0 deletions conversation/anthropic/anthropic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
Copyright 2024 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package anthropic

import (
"context"
"reflect"

"github.com/dapr/components-contrib/conversation"
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/kit/logger"
kmeta "github.com/dapr/kit/metadata"

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

type Anthropic struct {
llm *anthropic.LLM

logger logger.Logger
}

type AnthropicMetadata struct {
Key string `json:"key"`
Model string `json:"model"`
}

func NewAnthropic(logger logger.Logger) conversation.Conversation {
a := &Anthropic{
logger: logger,
}

return a
}

const defaultModel = "claude-3-5-sonnet-20240620"

func (a *Anthropic) Init(ctx context.Context, meta conversation.Metadata) error {
m := AnthropicMetadata{}
err := kmeta.DecodeMetadata(meta.Properties, &m)
if err != nil {
return err
}

model := defaultModel
if m.Model != "" {
model = m.Model
}

llm, err := anthropic.New(
anthropic.WithModel(model),
anthropic.WithToken(m.Key),
)
if err != nil {
return err
}

a.llm = llm
return nil
}

func (a *Anthropic) GetComponentMetadata() (metadataInfo metadata.MetadataMap) {
metadataStruct := AnthropicMetadata{}
metadata.GetMetadataInfoFromStructType(reflect.TypeOf(metadataStruct), &metadataInfo, metadata.ConversationType)
return
}

func (a *Anthropic) Converse(ctx context.Context, r *conversation.ConversationRequest) (res *conversation.ConversationResponse, err error) {
messages := make([]llms.MessageContent, 0, len(r.Inputs))

for _, input := range r.Inputs {
role := conversation.ConvertLangchainRole(input.Role)

messages = append(messages, llms.MessageContent{
Role: role,
Parts: []llms.ContentPart{
llms.TextPart(input.Message),
},
})
}

opts := []llms.CallOption{}

if r.Temperature > 0 {
opts = append(opts, conversation.LangchainTemperature(r.Temperature))
}

resp, err := a.llm.GenerateContent(ctx, messages, opts...)
if err != nil {
return nil, err
}

outputs := make([]conversation.ConversationResult, 0, len(resp.Choices))

for i := range resp.Choices {
outputs = append(outputs, conversation.ConversationResult{
Result: resp.Choices[i].Content,
Parameters: r.Parameters,
})
}

res = &conversation.ConversationResponse{
Outputs: outputs,
}

return res, nil
}

func (a *Anthropic) Close() error {
return nil
}
29 changes: 29 additions & 0 deletions conversation/anthropic/metadata.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# yaml-language-server: $schema=../../../component-metadata-schema.json
schemaVersion: v1
type: conversation
name: anthropic
version: v1
status: alpha
title: "Anthropic"
urls:
- title: Reference
url: https://docs.dapr.io/reference/components-reference/supported-conversation/setup-anthropic/
authenticationProfiles:
- title: "API Key"
description: "Authenticate using an API key"
metadata:
- name: key
type: string
required: true
sensitive: true
description: |
API key for Anthropic.
example: "**********"
default: ""
metadata:
- name: model
required: false
description: |
The Anthropic LLM to use. Defaults to claude-3-5-sonnet-20240620
type: string
example: 'claude-3-5-sonnet-20240620'
136 changes: 136 additions & 0 deletions conversation/aws/bedrock/bedrock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
Copyright 2024 The Dapr Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package bedrock

import (
"context"
"reflect"

awsAuth "github.com/dapr/components-contrib/common/authentication/aws"
"github.com/dapr/components-contrib/conversation"
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/kit/logger"
kmeta "github.com/dapr/kit/metadata"

"github.com/aws/aws-sdk-go-v2/service/bedrockruntime"
"github.com/tmc/langchaingo/llms"
"github.com/tmc/langchaingo/llms/bedrock"
)

type AWSBedrock struct {
model string
llm *bedrock.LLM

logger logger.Logger
}

type AWSBedrockMetadata struct {
Region string `json:"region"`
Endpoint string `json:"endpoint"`
AccessKey string `json:"accessKey"`
SecretKey string `json:"secretKey"`
SessionToken string `json:"sessionToken"`
Model string `json:"model"`
}

func NewAWSBedrock(logger logger.Logger) conversation.Conversation {
b := &AWSBedrock{
logger: logger,
}

return b
}

func (b *AWSBedrock) Init(ctx context.Context, meta conversation.Metadata) error {
m := AWSBedrockMetadata{}
err := kmeta.DecodeMetadata(meta.Properties, &m)
if err != nil {
return err
}

awsConfig, err := awsAuth.GetConfigV2(m.AccessKey, m.SecretKey, m.SessionToken, m.Region, m.Endpoint)
if err != nil {
return err
}

bedrockClient := bedrockruntime.NewFromConfig(awsConfig)

opts := []bedrock.Option{bedrock.WithClient(bedrockClient)}
if m.Model != "" {
opts = append(opts, bedrock.WithModel(m.Model))
}
b.model = m.Model

llm, err := bedrock.New(
opts...,
)
if err != nil {
return err
}

b.llm = llm
return nil
}

func (b *AWSBedrock) GetComponentMetadata() (metadataInfo metadata.MetadataMap) {
metadataStruct := AWSBedrockMetadata{}
metadata.GetMetadataInfoFromStructType(reflect.TypeOf(metadataStruct), &metadataInfo, metadata.ConversationType)
return
}

func (b *AWSBedrock) Converse(ctx context.Context, r *conversation.ConversationRequest) (res *conversation.ConversationResponse, err error) {
messages := make([]llms.MessageContent, 0, len(r.Inputs))

for _, input := range r.Inputs {
role := conversation.ConvertLangchainRole(input.Role)

messages = append(messages, llms.MessageContent{
Role: role,
Parts: []llms.ContentPart{
llms.TextPart(input.Message),
},
})
}

opts := []llms.CallOption{}

if r.Temperature > 0 {
opts = append(opts, conversation.LangchainTemperature(r.Temperature))
}

resp, err := b.llm.GenerateContent(ctx, messages, opts...)
if err != nil {
return nil, err
}

outputs := make([]conversation.ConversationResult, 0, len(resp.Choices))

for i := range resp.Choices {
outputs = append(outputs, conversation.ConversationResult{
Result: resp.Choices[i].Content,
Parameters: r.Parameters,
})
}

res = &conversation.ConversationResponse{
Outputs: outputs,
}

return res, nil
}

func (b *AWSBedrock) Close() error {
return nil
}
26 changes: 26 additions & 0 deletions conversation/aws/bedrock/metadata.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# yaml-language-server: $schema=../../../component-metadata-schema.json
schemaVersion: v1
type: conversation
name: aws.bedrock
version: v1
status: alpha
title: "AWS Bedrock"
urls:
- title: Reference
url: https://docs.dapr.io/reference/components-reference/supported-conversation/setup-aws-bedrock/
builtinAuthenticationProfiles:
- name: "aws"
metadata:
- name: endpoint
required: false
description: |
AWS endpoint for the component to use, to connect to emulators.
Do not use this when running against production AWS.
example: '"http://localhost:4566"'
type: string
- name: model
required: false
description: |
The LLM to use. Defaults to Bedrock's default provider model from Amazon.
type: string
example: 'amazon.titan-text-express-v1'
Loading

0 comments on commit 98b880f

Please sign in to comment.