@@ -42,37 +42,117 @@ const ENGINE_TO_WIRE_BY_PROFILE: Record<
4242 gpt : { ...DEFAULT_ENGINE_TO_WIRE , ...GPT_OVERRIDES } ,
4343} ;
4444
45- /** Tools the gpt profile folds into the single apply_patch envelope tool. */
46- const PATCH_FOLDED_ENGINES : ReadonlySet < string > = new Set ( [
47- "write_file" ,
48- "edit_file" ,
49- "delete_file" ,
50- ] ) ;
45+ /**
46+ * Engines one advertised wire replaces. A profile without an entry keeps
47+ * the 1:1 wire table. Adding a family is a new ToolProfile plus a row here
48+ * and in ENGINE_TO_WIRE_BY_PROFILE — not a new director package.
49+ */
50+ const PROFILE_FOLDS : Record <
51+ ToolProfile ,
52+ { wire : string ; engines : readonly string [ ] } | undefined
53+ > = {
54+ default : undefined ,
55+ gpt : {
56+ wire : "apply_patch" ,
57+ engines : [ "write_file" , "edit_file" , "delete_file" ] ,
58+ } ,
59+ } ;
60+
61+ function buildAdvertisedWireEngines (
62+ profile : ToolProfile ,
63+ ) : ReadonlyMap < string , readonly string [ ] > {
64+ const fold = PROFILE_FOLDS [ profile ] ;
65+ const folded = new Set ( fold ?. engines ?? [ ] ) ;
66+ const map = new Map < string , string [ ] > ( ) ;
67+ for ( const [ engine , wire ] of Object . entries (
68+ ENGINE_TO_WIRE_BY_PROFILE [ profile ] ,
69+ ) ) {
70+ if ( folded . has ( engine ) ) continue ;
71+ const existing = map . get ( wire ) ;
72+ if ( existing === undefined ) map . set ( wire , [ engine ] ) ;
73+ else existing . push ( engine ) ;
74+ }
75+ if ( fold !== undefined ) map . set ( fold . wire , [ ...fold . engines ] ) ;
76+ return map ;
77+ }
78+
79+ const ADVERTISED_WIRE_ENGINES = Object . fromEntries (
80+ ( Object . keys ( ENGINE_TO_WIRE_BY_PROFILE ) as ToolProfile [ ] ) . map ( ( profile ) => [
81+ profile ,
82+ buildAdvertisedWireEngines ( profile ) ,
83+ ] ) ,
84+ ) as Record < ToolProfile , ReadonlyMap < string , readonly string [ ] > > ;
85+
86+ export function toolProfiles ( ) : readonly ToolProfile [ ] {
87+ return Object . keys ( ENGINE_TO_WIRE_BY_PROFILE ) as ToolProfile [ ] ;
88+ }
89+
90+ /** Wire name → engine ids this profile advertises. Folded wires map to every engine they replace. */
91+ export function advertisedWireEngines (
92+ profile : ToolProfile ,
93+ ) : ReadonlyMap < string , readonly string [ ] > {
94+ return ADVERTISED_WIRE_ENGINES [ profile ] ;
95+ }
96+
97+ /**
98+ * Engines `wire` stands for on `profile`. Undefined when this profile does
99+ * not advertise that name (a later family follows the same table).
100+ */
101+ export function enginesForAdvertisedWire (
102+ wire : string ,
103+ profile : ToolProfile ,
104+ ) : readonly string [ ] | undefined {
105+ const table = ADVERTISED_WIRE_ENGINES [ profile ] ;
106+ return table . get ( wire ) ?? table . get ( wire . toLowerCase ( ) ) ;
107+ }
108+
109+ /** Wire this profile advertises for `engine`, including a fold that replaces it. */
110+ function profileWireName ( engine : string , profile : ToolProfile ) : string {
111+ const fold = PROFILE_FOLDS [ profile ] ;
112+ if ( fold !== undefined && fold . engines . includes ( engine ) ) return fold . wire ;
113+ return advertisedToolName ( engine , profile ) ;
114+ }
115+
116+ /** Every wire any profile advertises for `engine`, including fold wires. */
117+ export function advertisedNamesForEngine ( engine : string ) : readonly string [ ] {
118+ const names : string [ ] = [ ] ;
119+ const seen = new Set < string > ( ) ;
120+ for ( const profile of toolProfiles ( ) ) {
121+ const wire = profileWireName ( engine , profile ) ;
122+ if ( seen . has ( wire ) ) continue ;
123+ seen . add ( wire ) ;
124+ names . push ( wire ) ;
125+ }
126+ return names ;
127+ }
51128
52129/** gpt models are trained on apply_patch, not write/edit/delete. Other
53- * profiles and lists without a file-mutation tool pass through unchanged. */
130+ * profiles and lists without a folded tool pass through unchanged. */
54131export function foldFileToolNames (
55132 names : readonly string [ ] ,
56133 profile : ToolProfile ,
57134) : readonly string [ ] {
58- if ( profile !== "gpt" ) return names ;
135+ const fold = PROFILE_FOLDS [ profile ] ;
136+ if ( fold === undefined ) return names ;
59137 const folded = ( name : string ) : boolean =>
60- PATCH_FOLDED_ENGINES . has ( engineToolName ( name ) ) ;
138+ fold . engines . includes ( engineToolName ( name ) ) ;
61139 if ( ! names . some ( folded ) ) return names ;
62140 const first = names . findIndex ( folded ) ;
63141 return names . flatMap ( ( name , i ) =>
64- i === first ? [ "apply_patch" ] : folded ( name ) ? [ ] : [ name ] ,
142+ i === first ? [ fold . wire ] : folded ( name ) ? [ ] : [ name ] ,
65143 ) ;
66144}
67145
68146export function foldFileToolDefinitions (
69147 defs : readonly ToolDefinition [ ] ,
70148 profile : ToolProfile ,
71149) : ToolDefinition [ ] {
72- if ( profile !== "gpt" || ! defs . some ( ( d ) => d . name === "apply_patch" ) ) {
150+ const fold = PROFILE_FOLDS [ profile ] ;
151+ if ( fold === undefined || ! defs . some ( ( d ) => d . name === fold . wire ) ) {
73152 return [ ...defs ] ;
74153 }
75- return defs . filter ( ( d ) => ! PATCH_FOLDED_ENGINES . has ( engineToolName ( d . name ) ) ) ;
154+ const folded = new Set ( fold . engines ) ;
155+ return defs . filter ( ( d ) => ! folded . has ( engineToolName ( d . name ) ) ) ;
76156}
77157
78158export function toolProfileForFamily ( family : ModelFamily ) : ToolProfile {
@@ -128,16 +208,23 @@ export function advertisedToolName(
128208}
129209
130210/** True when `name` (wire, engine, or hidden alias) is covered by an
131- * advertised or activated listing (which may store wire or engine ids). */
211+ * advertised or activated listing (which may store wire or engine ids).
212+ * A call is advertised when this profile's wire is on the list, and also
213+ * when the default wire is — primary prefixes still store `bash` while a
214+ * gpt worker prefix stores `shell`. */
132215export function nameMatchesAdvertisedListing (
133216 name : string ,
134217 isListed : ( candidate : string ) => boolean ,
218+ profile : ToolProfile = "default" ,
135219) : boolean {
136220 if ( isListed ( name ) ) return true ;
137221 const engine = engineToolName ( name ) ;
138222 if ( engine !== name && isListed ( engine ) ) return true ;
139- const wire = advertisedToolName ( engine ) ;
140- return wire !== name && isListed ( wire ) ;
223+ const wires =
224+ profile === "default"
225+ ? [ profileWireName ( engine , profile ) ]
226+ : [ profileWireName ( engine , profile ) , profileWireName ( engine , "default" ) ] ;
227+ return wires . some ( ( wire ) => wire !== name && isListed ( wire ) ) ;
141228}
142229
143230// update_plan dispatches through translateUpdatePlanArgs, so advertising
0 commit comments