| 1 | package boot |
| 2 | |
| 3 | import ( |
| 4 | "reasonix/internal/agentpreset" |
| 5 | "reasonix/internal/tool" |
| 6 | ) |
| 7 | |
| 8 | // Role vocabulary re-exported for old frontends. Runtime constraints live in |
| 9 | // internal/runtimepolicy; these names only parse compat inputs. |
| 10 | |
| 11 | // AgentPreset label constants retained for wire compatibility. Every known |
| 12 | // value folds to standard and no longer changes runtime behavior. |
| 13 | const ( |
| 14 | AgentPresetStandard = string(agentpreset.Standard) |
| 15 | AgentPresetDelivery = string(agentpreset.Delivery) |
| 16 | ) |
| 17 | |
| 18 | // Deprecated compat aliases for one-version-old callers. |
| 19 | const ( |
| 20 | AgentPresetBalanced = AgentPresetStandard |
| 21 | TokenModeFull = "full" |
| 22 | TokenModeDelivery = "delivery" |
| 23 | ) |
| 24 | |
| 25 | // NormalizeAgentPreset maps free-form and legacy values to the canonical |
| 26 | // compatibility label. Known legacy values fold to standard; unknown values return the input |
| 27 | // unchanged so callers can surface an error. |
| 28 | func NormalizeAgentPreset(raw string) string { |
| 29 | if p, err := agentpreset.Normalize(raw); err == nil { |
| 30 | return string(p) |
| 31 | } |
| 32 | return raw |
| 33 | } |
| 34 | |
| 35 | // NormalizeAgentPresetErr is NormalizeAgentPreset reporting parse errors. |
| 36 | func NormalizeAgentPresetErr(raw string) (string, error) { |
| 37 | p, err := agentpreset.Normalize(raw) |
| 38 | return string(p), err |
| 39 | } |
| 40 | |
| 41 | // NormalizeTokenMode is the deprecated alias that returns the fixed full |
| 42 | // tokenMode value for older clients. |
| 43 | func NormalizeTokenMode(mode string) string { |
| 44 | return agentpreset.LegacyTokenMode(agentpreset.FromLegacyTokenMode(mode)) |
| 45 | } |
| 46 | |
| 47 | // AgentPresetFromTokenMode maps a legacy tokenMode onto a role setting. |
| 48 | func AgentPresetFromTokenMode(mode string) string { |
| 49 | return string(agentpreset.FromLegacyTokenMode(mode)) |
| 50 | } |
| 51 | |
| 52 | // TokenModeFromAgentPreset maps a role setting onto the dual-write tokenMode. |
| 53 | func TokenModeFromAgentPreset(preset string) string { |
| 54 | return agentpreset.LegacyTokenMode(agentpreset.FromLegacyTokenMode(preset)) |
| 55 | } |
| 56 | |
| 57 | // CoreProviderToolNames is the stable top-level tool surface shared by every |
| 58 | // Agent role setting under identical configuration. Host-control tools |
| 59 | // (ask, create_goal, get_goal, update_goal, todo_write) are appended when enabled. |
| 60 | func CoreProviderToolNames() []string { |
| 61 | return []string{ |
| 62 | "bash", |
| 63 | "job_output", |
| 64 | "job_kill", |
| 65 | "read_file", |
| 66 | "view_image", |
| 67 | "edit_file", |
| 68 | "write_file", |
| 69 | "compress", |
| 70 | "use_capability", |
| 71 | "web_search", |
| 72 | } |
| 73 | } |
| 74 | |
| 75 | func coreProviderToolNamesForRegistry(reg *tool.Registry) []string { |
| 76 | names := CoreProviderToolNames() |
| 77 | if reg == nil { |
| 78 | return names |
| 79 | } |
| 80 | if _, ok := reg.Get("pwsh"); !ok { |
| 81 | return names |
| 82 | } |
| 83 | for i, name := range names { |
| 84 | if name == "bash" { |
| 85 | names[i] = "pwsh" |
| 86 | break |
| 87 | } |
| 88 | } |
| 89 | return names |
| 90 | } |
| 91 | |
| 92 | // HostControlToolNames are collaboration/contract tools that may appear in the |
| 93 | // provider schema independently of the Agent role setting. |
| 94 | func HostControlToolNames() []string { |
| 95 | return []string{ |
| 96 | "ask", |
| 97 | "create_goal", |
| 98 | "get_goal", |
| 99 | "update_goal", |
| 100 | "todo_write", |
| 101 | } |
| 102 | } |
| 103 | |
| 104 | // UnifiedProviderToolNames returns the provider-visible allowlist for a boot |
| 105 | // with host-control tools enabled. |
| 106 | func UnifiedProviderToolNames() []string { |
| 107 | core := CoreProviderToolNames() |
| 108 | host := HostControlToolNames() |
| 109 | out := make([]string, 0, len(core)+len(host)) |
| 110 | out = append(out, core...) |
| 111 | out = append(out, host...) |
| 112 | return out |
| 113 | } |
| 114 | |
| 115 | // applyUnifiedProviderToolSurface restricts Schemas/ContractEntries to the |
| 116 | // shared core + host-control tools. use_capability can still Get every |
| 117 | // registered tool, including those hidden from the provider schema. |
| 118 | func applyUnifiedProviderToolSurface(reg *tool.Registry) { |
| 119 | if reg == nil { |
| 120 | return |
| 121 | } |
| 122 | allow := make([]string, 0, 16) |
| 123 | names := coreProviderToolNamesForRegistry(reg) |
| 124 | names = append(names, HostControlToolNames()...) |
| 125 | for _, name := range names { |
| 126 | if _, ok := reg.Get(name); ok { |
| 127 | allow = append(allow, name) |
| 128 | } |
| 129 | } |
| 130 | // Always keep use_capability if somehow only that remains. |
| 131 | if len(allow) == 0 { |
| 132 | if _, ok := reg.Get("use_capability"); ok { |
| 133 | allow = []string{"use_capability"} |
| 134 | } |
| 135 | } |
| 136 | reg.SetProviderVisibleTools(allow) |
| 137 | } |
| 138 |