Documentation
¶
Overview ¶
Package tokenless provides reusable helpers for hermetic end-to-end tests of agent apps: building a binary once per test run, running it as a subprocess against an in-test mock gateway, and asserting on newline-delimited JSON output and recorded expectation failures.
Index ¶
- func BuildBinary(srcDir, reuseEnvVar string) (string, func(), error)
- func CapturePane(session string) string
- func ContentsByRole(lines []map[string]any, role string) []string
- func JSONLines(t *testing.T, stdout string) []map[string]any
- func SendKeys(t *testing.T, session string, args ...string)
- func StatusOfType(lines []map[string]any, typ string) map[string]any
- func ToolMessages(body gateway.CreateChatCompletionRequest) []gateway.Message
- func WaitForPane(t *testing.T, session, want string, timeout time.Duration) bool
- func WriteFixtures(t *testing.T, dir string, names ...string)
- type Mock
- type Orchestrator
- type Result
- type TestingT
- type ToolFunc
- type ToolLoop
- type ToolLoopResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildBinary ¶
BuildBinary builds the Go main package at srcDir into a temp dir and returns the binary path plus a cleanup func. Intended for TestMain: build once, share the path across tests. Honors reuseEnvVar (e.g. "MYAPP_E2E_BINARY"): when that environment variable is set, its value is returned as-is and no build happens.
func CapturePane ¶
CapturePane returns the last 200 lines of the tmux session's pane, or "" if it cannot be read.
func ContentsByRole ¶
ContentsByRole returns the content of every line whose "role" matches.
func JSONLines ¶
JSONLines parses every non-empty stdout line into a generic map; headless agents emit newline-delimited JSON only.
func SendKeys ¶
SendKeys sends one send-keys call to the session (literal text needs a leading "-l" arg; named keys like Enter are passed bare).
func StatusOfType ¶
StatusOfType returns the first line whose "type" matches, or nil.
func ToolMessages ¶
func ToolMessages(body gateway.CreateChatCompletionRequest) []gateway.Message
ToolMessages returns the tool-role messages of a chat completion request.
func WaitForPane ¶
WaitForPane polls the pane until it contains want or timeout elapses.
Types ¶
type Mock ¶
Mock wraps the gateway server with test-friendly assertion methods.
func StartMock ¶
func StartMock(t *testing.T, defs ...*gateway.ScenarioFile) *Mock
StartMock serves a scenario library on an httptest server tied to the test's lifetime and returns the Mock. With no arguments the built-in library is served.
func (*Mock) AssertExpectations ¶
AssertExpectations fails the test if any expectation mismatches were recorded, printing a readable want/got diff for each failure.
type Orchestrator ¶
type Orchestrator struct {
Bin string
Dir string
Env map[string]string
Stdin string
Timeout time.Duration
}
Orchestrator describes the binary under test. Zero values work: Dir defaults to a fresh temp dir, Timeout to 30s. Env entries (typically at least the app's gateway-URL variable pointed at the mock) are appended on top of a hermetic base whose HOME is a temp dir, so the user's real config never leaks in.
type TestingT ¶
type TestingT interface {
Errorf(format string, args ...interface{})
Helper()
}
TestingT is the minimal interface for AssertExpectations, mirroring testify/mock's pattern so the library does not import "testing".
type ToolFunc ¶
ToolFunc is a real tool implementation: given the tool call's JSON args, it returns the string result to feed back as a role:tool message.
type ToolLoop ¶
type ToolLoop struct {
BaseURL string
Model string
Tools map[string]ToolFunc
// Context is the context passed to each ToolFunc invocation. If nil,
// context.Background() is used. Set this to inject test helpers (e.g.
// a *Mock for in-tool assertions) via context.WithValue.
Context context.Context
// Approve is an optional callback that decides whether a tool call
// should be executed. It receives the tool call and returns true to
// approve or false to reject. A rejected tool call returns a "denied"
// result to the model and the loop continues. If nil, all tool calls
// are approved (backward compatible).
Approve func(ctx context.Context, tc gateway.ChatCompletionMessageToolCall) bool
}
ToolLoop drives a multi-turn conversation against a tokenless mock, executing real tool implementations when the mock returns tool_calls. Unregistered tool names cause a test failure.
func (*ToolLoop) LoadScenarioTools ¶
func (l *ToolLoop) LoadScenarioTools(defs *gateway.ScenarioFile)
LoadScenarioTools reads the tools: block from a ScenarioFile and registers each exec-based tool as a ToolFunc that templates the argv from the tool call's JSON args and runs the resulting command.
func (*ToolLoop) Run ¶
func (l *ToolLoop) Run(t testing.TB, prompt string) *ToolLoopResult
Run sends prompt as a user message and loops until the model responds with content (no more tool_calls). Each tool_calls turn invokes the matching ToolFunc and feeds the real result back as a role:tool message.
type ToolLoopResult ¶
type ToolLoopResult struct {
FinalContent string
}
ToolLoopResult holds the final assistant content after all tool calls have been resolved.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
tokenless
command
Command tokenless serves the gateway scenario server as a standalone binary for manual testing and terminal-automation harnesses.
|
Command tokenless serves the gateway scenario server as a standalone binary for manual testing and terminal-automation harnesses. |
|
Package gateway implements a hermetic, deterministic mock of the LLM API surface agent apps consume: GET /v1/models, POST /v1/chat/completions (sync JSON and SSE streaming), POST /v1/messages (Anthropic-native), POST /v1/images/generations and /v1/images/edits, and GET /v1/health.
|
Package gateway implements a hermetic, deterministic mock of the LLM API surface agent apps consume: GET /v1/models, POST /v1/chat/completions (sync JSON and SSE streaming), POST /v1/messages (Anthropic-native), POST /v1/images/generations and /v1/images/edits, and GET /v1/health. |