feat: add MCP enums, ToolError, and Caller
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Caller invokes an MCP tool by name and returns its JSON result.
|
||||||
|
type Caller interface {
|
||||||
|
Call(ctx context.Context, name string, args map[string]any) (json.RawMessage, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Func adapts a function to Caller so tests can inject a stub.
|
||||||
|
type Func func(ctx context.Context, name string, args map[string]any) (json.RawMessage, error)
|
||||||
|
|
||||||
|
func (f Func) Call(ctx context.Context, name string, args map[string]any) (json.RawMessage, error) {
|
||||||
|
return f(ctx, name, args)
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
// Side is an order side. Values are Robinhood wire strings.
|
||||||
|
type Side string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Buy Side = "buy"
|
||||||
|
Sell Side = "sell"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OrderType is an order type. Values are Robinhood wire strings.
|
||||||
|
type OrderType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Market OrderType = "market"
|
||||||
|
Limit OrderType = "limit"
|
||||||
|
Stop OrderType = "stop_market" // equity + options; crypto uses StopLoss
|
||||||
|
StopLimit OrderType = "stop_limit"
|
||||||
|
StopLoss OrderType = "stop_loss" // crypto only
|
||||||
|
)
|
||||||
|
|
||||||
|
// TimeInForce is an order duration. Values are Robinhood wire strings.
|
||||||
|
type TimeInForce string
|
||||||
|
|
||||||
|
const (
|
||||||
|
GFD TimeInForce = "gfd"
|
||||||
|
GTC TimeInForce = "gtc"
|
||||||
|
GFW TimeInForce = "gfw" // crypto
|
||||||
|
GFM TimeInForce = "gfm" // crypto
|
||||||
|
)
|
||||||
|
|
||||||
|
// MarketHours is a trading-session window. Values are Robinhood wire strings.
|
||||||
|
type MarketHours string
|
||||||
|
|
||||||
|
const (
|
||||||
|
RegularHours MarketHours = "regular_hours"
|
||||||
|
ExtendedHours MarketHours = "extended_hours"
|
||||||
|
AllDayHours MarketHours = "all_day_hours"
|
||||||
|
RegularCurbHours MarketHours = "regular_curb_hours"
|
||||||
|
RegularCurbOvernightHours MarketHours = "regular_curb_overnight_hours"
|
||||||
|
)
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package client_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"s1d3sw1ped/robinhood-agentic-mcp/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEnums_wireValues(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
if client.Buy != "buy" || client.Stop != "stop_market" || client.StopLoss != "stop_loss" {
|
||||||
|
t.Fatal("side/type")
|
||||||
|
}
|
||||||
|
if client.GFD != "gfd" || client.RegularHours != "regular_hours" {
|
||||||
|
t.Fatal("tif/hours")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// ToolError is a failed MCP tool call or a parse of its result.
|
||||||
|
type ToolError struct {
|
||||||
|
Name string // MCP tool name
|
||||||
|
Message string
|
||||||
|
Err error // transport/SDK/parse cause; may be nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ToolError) Error() string {
|
||||||
|
return "mcp " + e.Name + ": " + e.Message
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ToolError) Unwrap() error {
|
||||||
|
return e.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToolErrorf builds a ToolError. format may use %w so Unwrap works.
|
||||||
|
func ToolErrorf(name, format string, args ...any) *ToolError {
|
||||||
|
err := fmt.Errorf(format, args...)
|
||||||
|
return &ToolError{
|
||||||
|
Name: name,
|
||||||
|
Message: err.Error(),
|
||||||
|
Err: err,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package client_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"s1d3sw1ped/robinhood-agentic-mcp/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestToolError_formatAndAs(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
inner := errors.New("boom")
|
||||||
|
err := client.ToolErrorf("get_accounts", "parse quotes: %w", inner)
|
||||||
|
if err.Error() != "mcp get_accounts: parse quotes: boom" {
|
||||||
|
t.Fatalf("%q", err.Error())
|
||||||
|
}
|
||||||
|
var te *client.ToolError
|
||||||
|
if !errors.As(err, &te) || te.Name != "get_accounts" {
|
||||||
|
t.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
if !errors.Is(err, inner) {
|
||||||
|
t.Fatal("unwrap")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user