Skip to content

CaliLuke/remedy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

remedy

remedy is a small Go library for structured business errors that help agents recover fast.

Most error packages stop at message + cause. That is enough for logs, but weak for agentic systems. An agent usually needs one more thing: a short, inline instruction telling it what to try next.

remedy packages that feedback into the error itself:

  • HTTP status for transports
  • Stable machine-readable codes for branching
  • Human-readable messages
  • Inline recovery guidance for agents, CLIs, and API clients
  • Standard error wrapping support

The practical benefit is token efficiency. Instead of failing with a vague message, then spending extra turns and tokens to explain recovery, your tool or API can return the fix with the failure.

remedy is also packaged with a companion agent skill. Install the skill alongside the library so agents have both the runtime API and the usage patterns for when to add recovery hints, how to format them at tool boundaries, and how to test them.

Install

go get github.com/CaliLuke/remedy@latest

Install the companion agent skill from this repository as well if your agents will be authoring or reviewing remedy usage.

Why Use It

Use remedy when the caller can take corrective action.

Good fit:

  • MCP tools and agent-facing APIs
  • validation-heavy services
  • HTTP or RPC layers that need status + error code mapping
  • CLI flows where the next step should be obvious

Less useful:

  • deep infrastructure errors with no user action
  • internal-only code paths where plain %w is enough

Example: Validation With Recovery

This is the core pattern extracted from Auto-K:

package main

import (
	"fmt"

	"github.com/CaliLuke/remedy"
)

func main() {
	err := remedy.NotFound("project %q was not found", "abc123").
		WithRecovery("Verify the project ID and retry")

	fmt.Println(remedy.GetStatus(err))
	fmt.Println(remedy.GetCode(err))
	fmt.Println(remedy.FormatForAgent(err))
}

Output:

404
not_found
[not_found] project "abc123" was not found
-> Recovery: Verify the project ID and retry

When you already have the pieces, use the shared formatter directly:

msg := remedy.FormatForAgentParts("not_found", "project was not found", "Verify the project ID and retry")

Example: Agent-Facing Tool Boundary

Format the error once, at the edge:

func codedErrorToTool(err error) string {
	return remedy.FormatForAgent(err)
}

That keeps the recovery hint inline with the failure, which is exactly what agent callers need to self-correct without wasting precious tokens on follow-up retries or extra explanation.

Example: Transport Mapping

Map remedy.Error at the HTTP or RPC boundary instead of scattering transport logic through service code.

func statusFromErr(err error) int {
	return remedy.GetStatus(err)
}

API

Constructor helpers:

  • remedy.BadRequest
  • remedy.Unauthorized
  • remedy.Forbidden
  • remedy.NotFound
  • remedy.Conflict
  • remedy.Internal
  • remedy.New

Fluent modifiers:

  • (*remedy.Error).WithCode
  • (*remedy.Error).WithRecovery
  • (*remedy.Error).Wrap

Consumers:

  • remedy.As
  • remedy.GetStatus
  • remedy.GetCode
  • remedy.GetRecovery
  • remedy.FormatForAgent
  • remedy.FormatForAgentParts

Design Rule

Create remedy errors close to the business rule that failed. Add WithRecovery(...) only when the caller can actually do something with it. Keep recovery text short, concrete, and immediately actionable.

About

Structured Go business errors with HTTP status, machine-readable codes, and recovery guidance

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages