Skip to content

Commit b0942a1

Browse files
authored
Merge branch 'main' into release-1.16
2 parents 862e30c + 959358a commit b0942a1

File tree

28 files changed

+294
-94
lines changed

28 files changed

+294
-94
lines changed

.github/scripts/dapr_bot.js

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,18 @@
11
// list of owner who can control dapr-bot workflow
22
// TODO: Read owners from OWNERS file.
33
const owners = [
4-
'addjuarez',
5-
'amuluyavarote',
6-
'artursouza',
4+
'acroca',
75
'berndverst',
6+
'cicoyle',
87
'daixiang0',
9-
'DeepanshuA',
10-
'elena-kolevska',
11-
'halspang',
12-
'ItalyPaleAle',
8+
'javier-aliaga',
139
'jjcollinge',
1410
'joshvanl',
1511
'mikeee',
1612
'msfussell',
17-
'mukundansundar',
18-
'pkedy',
19-
'pravinpushkar',
20-
'robertojrojas',
21-
'RyanLettieri',
22-
'shivamkm07',
23-
'shubham1172',
13+
'nelson-parente',
2414
'sicoyle',
25-
'skyao',
26-
'Taction',
27-
'tmacam',
2815
'yaron2',
29-
'yash-nisar',
3016
]
3117

3218
const docsIssueBodyTpl = (

bindings/sftp/sftp.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,13 @@ func (sftp *Sftp) create(_ context.Context, req *bindings.InvokeRequest) (*bindi
173173
return nil, fmt.Errorf("sftp binding error: error create file %s: %w", path, err)
174174
}
175175

176+
defer func() {
177+
closeErr := file.Close()
178+
if closeErr != nil {
179+
sftp.logger.Errorf("sftp binding error: error close file: %w", closeErr)
180+
}
181+
}()
182+
176183
_, err = file.Write(req.Data)
177184
if err != nil {
178185
return nil, fmt.Errorf("sftp binding error: error write file: %w", err)
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package sftp
2+
3+
import (
4+
"encoding/json"
5+
"os"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
11+
"github.com/dapr/components-contrib/bindings"
12+
)
13+
14+
var connectionStringEnvKey = "DAPR_TEST_SFTP_CONNSTRING"
15+
16+
// Run docker from the file location as the upload folder is relative to the test
17+
// docker run -v ./upload:/home/foo/upload -p 2222:22 -d atmoz/sftp foo:pass:1001
18+
func TestIntegrationCases(t *testing.T) {
19+
connectionString := os.Getenv(connectionStringEnvKey)
20+
if connectionString == "" {
21+
t.Skipf(`sftp binding integration tests skipped. To enable this test, define the connection string using environment variable '%[1]s' (example 'export %[1]s="localhost:2222")'`, connectionStringEnvKey)
22+
}
23+
24+
t.Run("List operation", testListOperation)
25+
t.Run("Create operation", testCreateOperation)
26+
}
27+
28+
func testListOperation(t *testing.T) {
29+
c := Sftp{}
30+
m := bindings.Metadata{}
31+
m.Properties = map[string]string{
32+
"rootPath": "/upload",
33+
"address": os.Getenv(connectionStringEnvKey),
34+
"username": "foo",
35+
"password": "pass",
36+
"insecureIgnoreHostKey": "true",
37+
}
38+
err := c.Init(t.Context(), m)
39+
require.NoError(t, err)
40+
41+
r, err := c.Invoke(t.Context(), &bindings.InvokeRequest{Operation: bindings.ListOperation})
42+
require.NoError(t, err)
43+
assert.NotNil(t, r.Data)
44+
45+
var d []listResponse
46+
err = json.Unmarshal(r.Data, &d)
47+
require.NoError(t, err)
48+
}
49+
50+
func testCreateOperation(t *testing.T) {
51+
c := Sftp{}
52+
m := bindings.Metadata{}
53+
m.Properties = map[string]string{
54+
"rootPath": "/upload",
55+
"address": os.Getenv(connectionStringEnvKey),
56+
"username": "foo",
57+
"password": "pass",
58+
"insecureIgnoreHostKey": "true",
59+
}
60+
61+
err := os.Remove("./upload/test.txt")
62+
if err != nil && !os.IsNotExist(err) {
63+
require.NoError(t, err)
64+
}
65+
66+
err = c.Init(t.Context(), m)
67+
require.NoError(t, err)
68+
69+
r, err := c.Invoke(t.Context(), &bindings.InvokeRequest{
70+
Operation: bindings.CreateOperation,
71+
Data: []byte("test data 1"),
72+
Metadata: map[string]string{
73+
"fileName": "test.txt",
74+
},
75+
})
76+
require.NoError(t, err)
77+
assert.NotNil(t, r.Data)
78+
79+
file, err := os.Stat("./upload/test.txt")
80+
require.NoError(t, err)
81+
assert.Equal(t, "test.txt", file.Name())
82+
}

conversation/anthropic/anthropic.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,15 @@ func NewAnthropic(logger logger.Logger) conversation.Conversation {
4141
return a
4242
}
4343

44-
const defaultModel = "claude-3-5-sonnet-20240620"
45-
4644
func (a *Anthropic) Init(ctx context.Context, meta conversation.Metadata) error {
4745
m := conversation.LangchainMetadata{}
4846
err := kmeta.DecodeMetadata(meta.Properties, &m)
4947
if err != nil {
5048
return err
5149
}
5250

53-
model := defaultModel
54-
if m.Model != "" {
55-
model = m.Model
56-
}
51+
// Resolve model via central helper (uses metadata, then env var, then default)
52+
model := conversation.GetAnthropicModel(m.Model)
5753

5854
llm, err := anthropic.New(
5955
anthropic.WithModel(model),

conversation/anthropic/metadata.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ metadata:
2424
- name: model
2525
required: false
2626
description: |
27-
The Anthropic LLM to use.
27+
The Anthropic LLM to use. Configurable via ANTHROPIC_MODEL environment variable.
2828
type: string
29-
example: 'claude-3-5-sonnet-20240620'
30-
default: 'claude-3-5-sonnet-20240620'
29+
example: 'claude-sonnet-4-20250514'
30+
default: 'claude-sonnet-4-20250514'
3131
- name: cacheTTL
3232
required: false
3333
description: |

conversation/googleai/googleai.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,15 @@ func NewGoogleAI(logger logger.Logger) conversation.Conversation {
4141
return g
4242
}
4343

44-
const defaultModel = "gemini-2.5-flash"
45-
4644
func (g *GoogleAI) Init(ctx context.Context, meta conversation.Metadata) error {
4745
md := conversation.LangchainMetadata{}
4846
err := kmeta.DecodeMetadata(meta.Properties, &md)
4947
if err != nil {
5048
return err
5149
}
5250

53-
model := defaultModel
54-
if md.Model != "" {
55-
model = md.Model
56-
}
51+
// Resolve model via central helper (uses metadata, then env var, then default)
52+
model := conversation.GetGoogleAIModel(md.Model)
5753

5854
opts := []openai.Option{
5955
openai.WithModel(model),

conversation/googleai/metadata.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ metadata:
2424
- name: model
2525
required: false
2626
description: |
27-
The GoogleAI LLM to use.
27+
The GoogleAI LLM to use. Configurable via GOOGLEAI_MODEL environment variable.
2828
type: string
29-
example: 'gemini-2.5-flash'
30-
default: 'gemini-2.5-flash'
29+
example: 'gemini-2.5-flash-lite'
30+
default: 'gemini-2.5-flash-lite'
3131
- name: cacheTTL
3232
required: false
3333
description: |

conversation/huggingface/huggingface.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ func NewHuggingface(logger logger.Logger) conversation.Conversation {
4242
return h
4343
}
4444

45-
// Default model - using a popular and reliable model
46-
const defaultModel = "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B"
47-
4845
// Default HuggingFace OpenAI-compatible endpoint
4946
const defaultEndpoint = "https://router.huggingface.co/hf-inference/models/{{model}}/v1"
5047

@@ -55,10 +52,8 @@ func (h *Huggingface) Init(ctx context.Context, meta conversation.Metadata) erro
5552
return err
5653
}
5754

58-
model := defaultModel
59-
if m.Model != "" {
60-
model = m.Model
61-
}
55+
// Resolve model via central helper (uses metadata, then env var, then default)
56+
model := conversation.GetHuggingFaceModel(m.Model)
6257

6358
endpoint := strings.Replace(defaultEndpoint, "{{model}}", model, 1)
6459
if m.Endpoint != "" {

conversation/huggingface/metadata.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ metadata:
2424
- name: model
2525
required: false
2626
description: |
27-
The Huggingface model to use. Uses OpenAI-compatible API.
27+
The Huggingface model to use. Uses OpenAI-compatible API. Configurable via HUGGINGFACE_MODEL environment variable.
2828
type: string
2929
example: 'deepseek-ai/DeepSeek-R1-Distill-Qwen-32B'
3030
default: 'deepseek-ai/DeepSeek-R1-Distill-Qwen-32B'

conversation/metadata_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func TestLangchainMetadata(t *testing.T) {
2525
t.Run("json marshaling with endpoint", func(t *testing.T) {
2626
metadata := LangchainMetadata{
2727
Key: "test-key",
28-
Model: "gpt-4",
28+
Model: DefaultOpenAIModel,
2929
CacheTTL: "10m",
3030
Endpoint: "https://custom-endpoint.example.com",
3131
}

0 commit comments

Comments
 (0)