Skip to content

Commit 80f4ed6

Browse files
committed
refactor: export backend struct types for external access
Export struct types to enable direct type references from external packages. Main changes: - Rename sandboxToolBackend to SandboxToolBackend in agentkit package - Rename backend to Backend in local package - Update NewSandboxToolBackend() return type from filesystem.Backend interface to concrete *SandboxToolBackend - Update NewBackend() return type from filesystem.Backend interface to concrete *Backend - Update all method receivers and test assertions to use the exported type names Impact: - External packages can now access the concrete backend types directly - Enables type assertions and direct struct field access when needed - Maintains backward compatibility since the types still implement filesystem.Backend interface
1 parent 1f91f54 commit 80f4ed6

File tree

4 files changed

+42
-43
lines changed

4 files changed

+42
-43
lines changed

adk/backend/agentkit/sandbox.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ type Config struct {
104104
ExecutionTimeout int
105105
}
106106

107-
type sandboxToolBackend struct {
107+
type SandboxToolBackend struct {
108108
secretAccessKey string
109109
accessKeyID string
110110
baseURL string
@@ -117,14 +117,14 @@ type sandboxToolBackend struct {
117117
executionTimeout int
118118
}
119119

120-
// NewSandboxToolBackend creates a new sandboxToolBackend instance.
121-
// sandboxToolBackend refers to the sandbox running instance created by the sandbox tool in Volcengine.
120+
// NewSandboxToolBackend creates a new SandboxToolBackend instance.
121+
// SandboxToolBackend refers to the sandbox running instance created by the sandbox tool in Volcengine.
122122
// For creating a sandbox tool environment, please refer to: https://www.volcengine.com/docs/86681/1847934?lang=zh;
123123
// For creating a sandbox tool running instance, please refer to: https://www.volcengine.com/docs/86681/1860266?lang=zh.
124124
// Note: The execution paths within the sandbox environment may be subject to permission restrictions (read, write, execute, etc.).
125125
// Improper path selection can result in operation failures or permission errors.
126126
// It is recommended to perform operations within paths where the sandbox environment has explicit permissions to mitigate permission-related risks.
127-
func NewSandboxToolBackend(config *Config) (filesystem.Backend, error) {
127+
func NewSandboxToolBackend(config *Config) (*SandboxToolBackend, error) {
128128
if config.AccessKeyID == "" {
129129
return nil, fmt.Errorf("AccessKeyID is required")
130130
}
@@ -159,7 +159,7 @@ func NewSandboxToolBackend(config *Config) (filesystem.Backend, error) {
159159
return nil, fmt.Errorf("invalid region: %s", region)
160160
}
161161

162-
return &sandboxToolBackend{
162+
return &SandboxToolBackend{
163163
accessKeyID: config.AccessKeyID,
164164
secretAccessKey: config.SecretAccessKey,
165165
httpClient: httpClient,
@@ -174,7 +174,7 @@ func NewSandboxToolBackend(config *Config) (filesystem.Backend, error) {
174174
}
175175

176176
// LsInfo lists file information under the given path.
177-
func (s *sandboxToolBackend) LsInfo(ctx context.Context, req *filesystem.LsInfoRequest) ([]filesystem.FileInfo, error) {
177+
func (s *SandboxToolBackend) LsInfo(ctx context.Context, req *filesystem.LsInfoRequest) ([]filesystem.FileInfo, error) {
178178
path, err := formatPath(req.Path, "/", true)
179179
if err != nil {
180180
return nil, err
@@ -216,7 +216,7 @@ func (s *sandboxToolBackend) LsInfo(ctx context.Context, req *filesystem.LsInfoR
216216
}
217217

218218
// Read reads file content with support for line-based offset and limit.
219-
func (s *sandboxToolBackend) Read(ctx context.Context, req *filesystem.ReadRequest) (string, error) {
219+
func (s *SandboxToolBackend) Read(ctx context.Context, req *filesystem.ReadRequest) (string, error) {
220220
path, err := formatPath(req.FilePath, "", true)
221221
if err != nil {
222222
return "", err
@@ -251,7 +251,7 @@ func (s *sandboxToolBackend) Read(ctx context.Context, req *filesystem.ReadReque
251251
}
252252

253253
// GrepRaw searches for content matching the specified pattern in files.
254-
func (s *sandboxToolBackend) GrepRaw(ctx context.Context, req *filesystem.GrepRequest) ([]filesystem.GrepMatch, error) {
254+
func (s *SandboxToolBackend) GrepRaw(ctx context.Context, req *filesystem.GrepRequest) ([]filesystem.GrepMatch, error) {
255255
path, _ := formatPath(req.Path, "", false)
256256
params := map[string]any{
257257
"pattern": req.Pattern,
@@ -292,7 +292,7 @@ func (s *sandboxToolBackend) GrepRaw(ctx context.Context, req *filesystem.GrepRe
292292
}
293293

294294
// GlobInfo returns file information matching the glob pattern.
295-
func (s *sandboxToolBackend) GlobInfo(ctx context.Context, req *filesystem.GlobInfoRequest) ([]filesystem.FileInfo, error) {
295+
func (s *SandboxToolBackend) GlobInfo(ctx context.Context, req *filesystem.GlobInfoRequest) ([]filesystem.FileInfo, error) {
296296
path, _ := formatPath(req.Path, "/", false)
297297
params := map[string]any{
298298
"path_b64": base64.StdEncoding.EncodeToString([]byte(path)),
@@ -330,7 +330,7 @@ func (s *sandboxToolBackend) GlobInfo(ctx context.Context, req *filesystem.GlobI
330330
}
331331

332332
// Write creates file content.
333-
func (s *sandboxToolBackend) Write(ctx context.Context, req *filesystem.WriteRequest) error {
333+
func (s *SandboxToolBackend) Write(ctx context.Context, req *filesystem.WriteRequest) error {
334334
path, err := formatPath(req.FilePath, "", true)
335335
if err != nil {
336336
return err
@@ -358,7 +358,7 @@ func (s *sandboxToolBackend) Write(ctx context.Context, req *filesystem.WriteReq
358358
}
359359

360360
// Edit replaces string occurrences in a file.
361-
func (s *sandboxToolBackend) Edit(ctx context.Context, req *filesystem.EditRequest) error {
361+
func (s *SandboxToolBackend) Edit(ctx context.Context, req *filesystem.EditRequest) error {
362362
path, err := formatPath(req.FilePath, "", true)
363363
if err != nil {
364364
return err
@@ -401,7 +401,7 @@ func (s *sandboxToolBackend) Edit(ctx context.Context, req *filesystem.EditReque
401401
}
402402

403403
// execute executes a command in the sandbox.
404-
func (s *sandboxToolBackend) execute(ctx context.Context, command string) (text string, exitCode *int, err error) {
404+
func (s *SandboxToolBackend) execute(ctx context.Context, command string) (text string, exitCode *int, err error) {
405405
var operationPayload string
406406
if s.executionTimeout <= 0 {
407407
operationPayload, err = sonic.MarshalString(map[string]any{
@@ -473,7 +473,7 @@ func (s *sandboxToolBackend) execute(ctx context.Context, command string) (text
473473
return text, exitCode, nil
474474
}
475475

476-
func (s *sandboxToolBackend) invokeTool(ctx context.Context, method string, body []byte) ([]byte, error) {
476+
func (s *SandboxToolBackend) invokeTool(ctx context.Context, method string, body []byte) ([]byte, error) {
477477
queries := make(url.Values)
478478
queries.Set("Action", "InvokeTool")
479479
queries.Set("Version", "2025-10-30")
@@ -506,7 +506,7 @@ func (s *sandboxToolBackend) invokeTool(ctx context.Context, method string, body
506506
return responseBody, nil
507507
}
508508

509-
func (s *sandboxToolBackend) signRequest(request *http.Request, queries url.Values, body []byte) {
509+
func (s *SandboxToolBackend) signRequest(request *http.Request, queries url.Values, body []byte) {
510510
now := time.Now()
511511
date := now.UTC().Format("20060102T150405Z")
512512
authDate := date[:8]
@@ -558,7 +558,7 @@ func (s *sandboxToolBackend) signRequest(request *http.Request, queries url.Valu
558558
request.Header.Set("Authorization", authorization)
559559
}
560560

561-
func (s *sandboxToolBackend) Execute(ctx context.Context, input *filesystem.ExecuteRequest) (result *filesystem.ExecuteResponse, err error) {
561+
func (s *SandboxToolBackend) Execute(ctx context.Context, input *filesystem.ExecuteRequest) (result *filesystem.ExecuteResponse, err error) {
562562
if input.Command == "" {
563563
return nil, fmt.Errorf("command is required")
564564
}

adk/backend/agentkit/sandbox_test.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ func TestNewArkSandbox(t *testing.T) {
4040
SessionTTL: 3600,
4141
ExecutionTimeout: 60,
4242
}
43-
ss, err := NewSandboxToolBackend(config)
44-
s := ss.(*sandboxToolBackend)
43+
s, err := NewSandboxToolBackend(config)
44+
4545
require.NoError(t, err)
4646
require.NotNil(t, s)
4747
assert.Equal(t, "test-ak", s.accessKeyID)
@@ -61,8 +61,8 @@ func TestNewArkSandbox(t *testing.T) {
6161
ToolID: "test-tool",
6262
UserSessionID: "test-session",
6363
}
64-
ss, err := NewSandboxToolBackend(config)
65-
s := ss.(*sandboxToolBackend)
64+
s, err := NewSandboxToolBackend(config)
65+
6666
require.NoError(t, err)
6767
require.NotNil(t, s)
6868
assert.Equal(t, RegionOfBeijing, s.region)
@@ -115,7 +115,7 @@ func TestNewArkSandbox(t *testing.T) {
115115
var mockAPIHandler http.HandlerFunc
116116

117117
// setupTest creates a mock server and an ArkSandbox client configured to use it.
118-
func setupTest(t *testing.T) (*sandboxToolBackend, *httptest.Server) {
118+
func setupTest(t *testing.T) (*SandboxToolBackend, *httptest.Server) {
119119
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
120120
if mockAPIHandler != nil {
121121
mockAPIHandler(w, r)
@@ -131,8 +131,7 @@ func setupTest(t *testing.T) (*sandboxToolBackend, *httptest.Server) {
131131
UserSessionID: "test-session",
132132
HTTPClient: server.Client(),
133133
}
134-
ss, err := NewSandboxToolBackend(config)
135-
sandbox := ss.(*sandboxToolBackend)
134+
sandbox, err := NewSandboxToolBackend(config)
136135
require.NoError(t, err)
137136
sandbox.baseURL = server.URL // Override to point to the mock server
138137

adk/backend/local/local.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,22 @@ type Config struct {
4040
ValidateCommand func(string) error
4141
}
4242

43-
type backend struct {
43+
type Backend struct {
4444
validateCommand func(string) error
4545
}
4646

4747
var defaultValidateCommand = func(string) error {
4848
return nil
4949
}
5050

51-
// NewBackend creates a new local filesystem backend instance.
51+
// NewBackend creates a new local filesystem Backend instance.
5252
//
5353
// IMPORTANT - System Compatibility:
5454
// - Supported: Unix/MacOS only
5555
// - NOT Supported: Windows (requires custom implementation of Backend)
5656
// - Command Execution: Uses /bin/sh by default for Execute method
5757
// - If /bin/sh does not meet your requirements, please implement your own Backend
58-
func NewBackend(_ context.Context, cfg *Config) (filesystem.Backend, error) {
58+
func NewBackend(_ context.Context, cfg *Config) (*Backend, error) {
5959
if cfg == nil {
6060
return nil, errors.New("config is required")
6161
}
@@ -65,12 +65,12 @@ func NewBackend(_ context.Context, cfg *Config) (filesystem.Backend, error) {
6565
validateCommand = cfg.ValidateCommand
6666
}
6767

68-
return &backend{
68+
return &Backend{
6969
validateCommand: validateCommand,
7070
}, nil
7171
}
7272

73-
func (s *backend) LsInfo(ctx context.Context, req *filesystem.LsInfoRequest) ([]filesystem.FileInfo, error) {
73+
func (s *Backend) LsInfo(ctx context.Context, req *filesystem.LsInfoRequest) ([]filesystem.FileInfo, error) {
7474
if req.Path == "" {
7575
req.Path = defaultRootPath
7676
}
@@ -105,7 +105,7 @@ func (s *backend) LsInfo(ctx context.Context, req *filesystem.LsInfoRequest) ([]
105105
return files, nil
106106
}
107107

108-
func (s *backend) Read(ctx context.Context, req *filesystem.ReadRequest) (string, error) {
108+
func (s *Backend) Read(ctx context.Context, req *filesystem.ReadRequest) (string, error) {
109109
path := filepath.Clean(req.FilePath)
110110
if !filepath.IsAbs(path) {
111111
return "", fmt.Errorf("path must be an absolute path: %s", path)
@@ -160,7 +160,7 @@ func (s *backend) Read(ctx context.Context, req *filesystem.ReadRequest) (string
160160
return result.String(), nil
161161
}
162162

163-
func (s *backend) GrepRaw(ctx context.Context, req *filesystem.GrepRequest) ([]filesystem.GrepMatch, error) {
163+
func (s *Backend) GrepRaw(ctx context.Context, req *filesystem.GrepRequest) ([]filesystem.GrepMatch, error) {
164164
path := filepath.Clean(req.Path)
165165

166166
var matches []filesystem.GrepMatch
@@ -232,7 +232,7 @@ func (s *backend) GrepRaw(ctx context.Context, req *filesystem.GrepRequest) ([]f
232232
return matches, nil
233233
}
234234

235-
func (s *backend) GlobInfo(ctx context.Context, req *filesystem.GlobInfoRequest) ([]filesystem.FileInfo, error) {
235+
func (s *Backend) GlobInfo(ctx context.Context, req *filesystem.GlobInfoRequest) ([]filesystem.FileInfo, error) {
236236
if req.Path == "" {
237237
req.Path = defaultRootPath
238238
}
@@ -337,7 +337,7 @@ func globToRegex(pattern string) (*regexp.Regexp, error) {
337337
return regexp.Compile(pattern)
338338
}
339339

340-
func (s *backend) Write(ctx context.Context, req *filesystem.WriteRequest) error {
340+
func (s *Backend) Write(ctx context.Context, req *filesystem.WriteRequest) error {
341341
if !filepath.IsAbs(req.FilePath) {
342342
return fmt.Errorf("path must be an absolute path: %s", req.FilePath)
343343
}
@@ -364,7 +364,7 @@ func (s *backend) Write(ctx context.Context, req *filesystem.WriteRequest) error
364364
return nil
365365
}
366366

367-
func (s *backend) Edit(ctx context.Context, req *filesystem.EditRequest) error {
367+
func (s *Backend) Edit(ctx context.Context, req *filesystem.EditRequest) error {
368368
path := filepath.Clean(req.FilePath)
369369
if !filepath.IsAbs(path) {
370370
return fmt.Errorf("path must be an absolute path: %s", path)
@@ -403,7 +403,7 @@ func (s *backend) Edit(ctx context.Context, req *filesystem.EditRequest) error {
403403
return os.WriteFile(path, []byte(newText), 0644)
404404
}
405405

406-
func (s *backend) ExecuteStreaming(ctx context.Context, input *filesystem.ExecuteRequest) (result *schema.StreamReader[*filesystem.ExecuteResponse], err error) {
406+
func (s *Backend) ExecuteStreaming(ctx context.Context, input *filesystem.ExecuteRequest) (result *schema.StreamReader[*filesystem.ExecuteResponse], err error) {
407407
if input.Command == "" {
408408
return nil, fmt.Errorf("command is required")
409409
}

adk/backend/local/local_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ func TestExecuteStreaming(t *testing.T) {
465465

466466
t.Run("ExecuteStreaming with echo", func(t *testing.T) {
467467
req := &filesystem.ExecuteRequest{Command: "echo line1 && echo line2 && echo line3"}
468-
sr, err := s.(*backend).ExecuteStreaming(ctx, req)
468+
sr, err := s.ExecuteStreaming(ctx, req)
469469
assert.NoError(t, err)
470470

471471
var outputs []string
@@ -487,7 +487,7 @@ func TestExecuteStreaming(t *testing.T) {
487487

488488
t.Run("ExecuteStreaming with ping", func(t *testing.T) {
489489
req := &filesystem.ExecuteRequest{Command: "ping -c 3 127.0.0.1"}
490-
sr, err := s.(*backend).ExecuteStreaming(ctx, req)
490+
sr, err := s.ExecuteStreaming(ctx, req)
491491
assert.NoError(t, err)
492492

493493
var lineCount int
@@ -506,7 +506,7 @@ func TestExecuteStreaming(t *testing.T) {
506506

507507
t.Run("ExecuteStreaming with seq command", func(t *testing.T) {
508508
req := &filesystem.ExecuteRequest{Command: "seq 1 5"}
509-
sr, err := s.(*backend).ExecuteStreaming(ctx, req)
509+
sr, err := s.ExecuteStreaming(ctx, req)
510510
assert.NoError(t, err)
511511

512512
var numbers []string
@@ -530,7 +530,7 @@ func TestExecuteStreaming(t *testing.T) {
530530
defer cancel()
531531

532532
req := &filesystem.ExecuteRequest{Command: "seq 1 1000000"}
533-
sr, err := s.(*backend).ExecuteStreaming(cancelCtx, req)
533+
sr, err := s.ExecuteStreaming(cancelCtx, req)
534534
assert.NoError(t, err)
535535

536536
var lineCount int
@@ -552,7 +552,7 @@ func TestExecuteStreaming(t *testing.T) {
552552

553553
t.Run("ExecuteStreaming with command failure", func(t *testing.T) {
554554
req := &filesystem.ExecuteRequest{Command: "echo output && exit 1"}
555-
sr, err := s.(*backend).ExecuteStreaming(ctx, req)
555+
sr, err := s.ExecuteStreaming(ctx, req)
556556
assert.NoError(t, err)
557557

558558
var hasOutput bool
@@ -575,7 +575,7 @@ func TestExecuteStreaming(t *testing.T) {
575575

576576
t.Run("ExecuteStreaming with stderr output", func(t *testing.T) {
577577
req := &filesystem.ExecuteRequest{Command: "echo stdout && echo stderr >&2 && exit 1"}
578-
sr, err := s.(*backend).ExecuteStreaming(ctx, req)
578+
sr, err := s.ExecuteStreaming(ctx, req)
579579
assert.NoError(t, err)
580580

581581
var outputs []string
@@ -600,14 +600,14 @@ func TestExecuteStreaming(t *testing.T) {
600600

601601
t.Run("ExecuteStreaming with empty command", func(t *testing.T) {
602602
req := &filesystem.ExecuteRequest{Command: ""}
603-
_, err := s.(*backend).ExecuteStreaming(ctx, req)
603+
_, err := s.ExecuteStreaming(ctx, req)
604604
assert.Error(t, err)
605605
assert.Contains(t, err.Error(), "command is required")
606606
})
607607

608608
t.Run("ExecuteStreaming with large output", func(t *testing.T) {
609609
req := &filesystem.ExecuteRequest{Command: "seq 1 100"}
610-
sr, err := s.(*backend).ExecuteStreaming(ctx, req)
610+
sr, err := s.ExecuteStreaming(ctx, req)
611611
assert.NoError(t, err)
612612

613613
var lineCount int
@@ -626,7 +626,7 @@ func TestExecuteStreaming(t *testing.T) {
626626

627627
t.Run("ExecuteStreaming with normal completion", func(t *testing.T) {
628628
req := &filesystem.ExecuteRequest{Command: "echo test"}
629-
sr, err := s.(*backend).ExecuteStreaming(ctx, req)
629+
sr, err := s.ExecuteStreaming(ctx, req)
630630
assert.NoError(t, err)
631631

632632
var receivedOutput bool
@@ -645,7 +645,7 @@ func TestExecuteStreaming(t *testing.T) {
645645

646646
t.Run("ExecuteStreaming with invalid command", func(t *testing.T) {
647647
req := &filesystem.ExecuteRequest{Command: "/nonexistent/command"}
648-
sr, err := s.(*backend).ExecuteStreaming(ctx, req)
648+
sr, err := s.ExecuteStreaming(ctx, req)
649649
assert.NoError(t, err)
650650

651651
var lastErr error

0 commit comments

Comments
 (0)