Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 15 additions & 17 deletions agent/harness/agentmode/agentmode.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ func New(cfg Config) *Provider {

// Validate modes: no empty names, no duplicates.
validModes := make(map[string]struct{}, len(modes))
modeNames := make([]string, 0, len(modes))
for i, m := range modes {
if strings.TrimSpace(m.Name) == "" {
panic(fmt.Sprintf("agentmode: mode at index %d has an empty name", i))
Expand All @@ -138,16 +139,18 @@ func New(cfg Config) *Provider {
panic(fmt.Sprintf("agentmode: duplicate mode name %q", m.Name))
}
validModes[m.Name] = struct{}{}
modeNames = append(modeNames, m.Name)
}
if _, ok := validModes[defaultMode]; !ok {
panic(fmt.Sprintf("agentmode: default mode %q is not in the configured modes list", defaultMode))
}

p := &Provider{
modes: modes,
defaultMode: defaultMode,
instructions: instructions,
validModes: validModes,
modes: modes,
defaultMode: defaultMode,
instructions: instructions,
validModes: validModes,
modeNamesDisplay: strings.Join(modeNames, "\", \""),
}

p.provider = agent.NewContextProvider(agent.ContextProviderConfig{
Expand All @@ -160,11 +163,12 @@ func New(cfg Config) *Provider {
// Provider is an agent mode context provider.
// Use [New] to create. Provider can be used directly in agent configuration.
type Provider struct {
provider agent.ContextProvider
modes []Mode
defaultMode string
instructions string
validModes map[string]struct{}
provider agent.ContextProvider
modes []Mode
defaultMode string
instructions string
validModes map[string]struct{}
modeNamesDisplay string

sessionLocks sync.Map // map[weak.Pointer[agent.Session]]*sync.Mutex
nullSessionLock sync.Mutex
Expand Down Expand Up @@ -286,20 +290,14 @@ func (p *Provider) buildInstructions(currentMode string) string {
}

func (p *Provider) createTools(opts []agent.Option) []tool.FuncTool {
modeNames := make([]string, len(p.modes))
for i, m := range p.modes {
modeNames[i] = m.Name
}
modeNamesDisplay := strings.Join(modeNames, "\", \"")

setTool := functool.MustNew(
functool.Config{
Name: "mode_set",
Description: fmt.Sprintf("Switch the agent's operating mode. Supported modes: \"%s\".", modeNamesDisplay),
Description: fmt.Sprintf("Switch the agent's operating mode. Supported modes: \"%s\".", p.modeNamesDisplay),
},
func(ctx context.Context, mode string) (string, error) {
if _, ok := p.validModes[mode]; !ok {
return "", fmt.Errorf("invalid mode: %q. Supported modes: \"%s\"", mode, modeNamesDisplay)
return "", fmt.Errorf("invalid mode: %q. Supported modes: \"%s\"", mode, p.modeNamesDisplay)
}
mu := p.getSessionLock(opts)
mu.Lock()
Expand Down
Loading