mirror of
https://github.com/docker/docker-agent.git
synced 2026-11-06 15:07:58 +00:00
Tool handlers previously reached back into the runtime through two context keys (ToolOutputEmitter, ToolRecallEmitter), each with its own With*/FromContext/Emit* boilerplate, invisible in the handler signature and requiring ad-hoc lifetime tricks (context.WithoutCancel + closure capture) for background work. Replace both with a single tools.Runtime capability handle passed explicitly to every handler: - ToolHandler is now func(ctx, ToolCall, rt Runtime); runtime-managed handlers (toolexec.ToolHandler) grow the same parameter, unifying the two tool APIs on one capability surface - Runtime methods (EmitOutput, Recall, Supports) take ctx per call and remain valid after the handler returns, so background jobs hold the handle instead of a captured closure - NopRuntime serves hosts without an agent loop (slash commands, prompt expansion, tests); Supports() lets tools fail fast before starting background work - NewHandler keeps its signature; NewRuntimeHandler is the variant for tools that talk back (shell streaming/recall, codemode forwarding) - codemode forwards the handle into script-invoked tools, preserving the nested-capability inheritance the ctx transport gave implicitly
59 lines
1.5 KiB
Go
59 lines
1.5 KiB
Go
package codemode
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/docker/docker-agent/pkg/tools"
|
|
)
|
|
|
|
func TestRunJavascript(t *testing.T) {
|
|
t.Parallel()
|
|
tool := &codeModeTool{}
|
|
|
|
result, err := tool.runJavascript(t.Context(), tools.NopRuntime{}, `return "HELLO"`)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "HELLO", result.Value)
|
|
assert.Empty(t, result.StdOut)
|
|
assert.Empty(t, result.StdErr)
|
|
}
|
|
|
|
func TestRunJavascript_error(t *testing.T) {
|
|
t.Parallel()
|
|
tool := &codeModeTool{}
|
|
|
|
result, err := tool.runJavascript(t.Context(), tools.NopRuntime{}, `==`)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "SyntaxError: SyntaxError: (anonymous): Line 2:1 Unexpected token == (and 2 more errors)", result.Value)
|
|
assert.Empty(t, result.StdOut)
|
|
assert.Empty(t, result.StdErr)
|
|
}
|
|
|
|
func TestRunJavascript_console(t *testing.T) {
|
|
t.Parallel()
|
|
tool := &codeModeTool{}
|
|
|
|
result, err := tool.runJavascript(t.Context(), tools.NopRuntime{}, `console.log("to stdout"); console.error("to stderr"); return "RESULT";`)
|
|
require.NoError(t, err)
|
|
|
|
assert.Equal(t, "RESULT", result.Value)
|
|
assert.Equal(t, "to stdout\n", result.StdOut)
|
|
assert.Equal(t, "to stderr\n", result.StdErr)
|
|
}
|
|
|
|
func TestRunJavascript_no_result(t *testing.T) {
|
|
t.Parallel()
|
|
tool := &codeModeTool{}
|
|
|
|
result, err := tool.runJavascript(t.Context(), tools.NopRuntime{}, ``)
|
|
require.NoError(t, err)
|
|
|
|
assert.Empty(t, result.Value)
|
|
assert.Empty(t, result.StdOut)
|
|
assert.Empty(t, result.StdErr)
|
|
}
|