@@ -28,6 +28,7 @@ const FAIL_POLICIES: InferenceFailPolicy[] = [
2828 "drop_family" , "text_only" , "error" ,
2929] ;
3030const ADAPTERS = [ "none" , "cpp" , "rust" , "go" , "python" ] as const ;
31+ type AdapterName = typeof ADAPTERS [ number ] ;
3132
3233export function SideChannelsTab ( {
3334 sideChannels, availableChannels, selectedTrainChannels, gotchas, onApply,
@@ -42,7 +43,8 @@ export function SideChannelsTab({
4243 standard : "c++20" ,
4344 } ) ;
4445 const [ prompt , setPrompt ] = useState ( "int add(int a, int b) { return a + b; }" ) ;
45- const [ adapter , setAdapter ] = useState < typeof ADAPTERS [ number ] > ( "cpp" ) ;
46+ const [ adapter , setAdapter ] = useState < AdapterName > ( "cpp" ) ;
47+ const [ tensorPreview , setTensorPreview ] = useState < string [ ] > ( [ ] ) ;
4648
4749 useEffect ( ( ) => setDraft ( sideChannels ) , [ sideChannels ] ) ;
4850
@@ -245,6 +247,15 @@ export function SideChannelsTab({
245247 onChange = { ( e ) => setPrompt ( e . target . value ) }
246248 style = { { width : "100%" , minHeight : 54 ,
247249 fontFamily : "monospace" , fontSize : 11 } } />
250+ < button data-testid = "side-channel-preview-run"
251+ onClick = { ( ) => setTensorPreview ( buildTensorPreview ( {
252+ sideChannels : draft ,
253+ prompt,
254+ platformPreview,
255+ adapter,
256+ } ) ) } >
257+ Build preview
258+ </ button >
248259 < pre data-testid = "side-channel-preview" style = { preview } >
249260{ `tokens=${ prompt . length }
250261source=${ draft . inference . source }
@@ -253,6 +264,9 @@ adapter=${adapter}
253264platform=${ platformPreview || "unspecified" }
254265families=${ enabledFamilies . join ( "," ) || "none" } ` }
255266 </ pre >
267+ < pre data-testid = "side-channel-preview-tensors" style = { preview } >
268+ { tensorPreview . length === 0 ? "not built" : tensorPreview . join ( "\n" ) }
269+ </ pre >
256270 </ section >
257271
258272 < section data-testid = "side-channel-probe" style = { section } >
@@ -305,6 +319,48 @@ families=${enabledFamilies.join(",") || "none"}`}
305319 }
306320}
307321
322+ function buildTensorPreview ( {
323+ sideChannels,
324+ prompt,
325+ platformPreview,
326+ adapter,
327+ } : {
328+ sideChannels : SideChannelState ;
329+ prompt : string ;
330+ platformPreview : string ;
331+ adapter : AdapterName ;
332+ } ) : string [ ] {
333+ const tokenCount = prompt . length ;
334+ const lines = [ `prompt_ids shape=(1,${ tokenCount } ) dtype=int32` ] ;
335+ if ( sideChannels . inference . source === "none" ) {
336+ lines . push ( "side_channels=none" ) ;
337+ return lines ;
338+ }
339+
340+ if ( sideChannels . families . platform ?. mode !== "off" && platformPreview ) {
341+ lines . push ( "platform_ids shape=(1,5) family=platform dtype=int32" ) ;
342+ }
343+
344+ const parsesSource = (
345+ adapter !== "none" &&
346+ [ "parse_if_possible" , "project_index" , "auto" ] . includes (
347+ sideChannels . inference . source ,
348+ )
349+ ) ;
350+ if ( parsesSource && sideChannels . families . structure ?. mode !== "off" ) {
351+ lines . push ( `structure_ids shape=(1,${ tokenCount } ) family=structure dtype=int32` ) ;
352+ lines . push ( `dep_levels shape=(1,${ tokenCount } ) family=structure dtype=int32` ) ;
353+ }
354+ if ( parsesSource && sideChannels . families . syntax ?. mode !== "off" ) {
355+ lines . push ( `ast_depth_ids shape=(1,${ tokenCount } ) family=syntax dtype=int32` ) ;
356+ lines . push ( `sibling_index_ids shape=(1,${ tokenCount } ) family=syntax dtype=int32` ) ;
357+ lines . push ( `node_type_ids shape=(1,${ tokenCount } ) family=syntax dtype=int32` ) ;
358+ }
359+
360+ if ( lines . length === 1 ) lines . push ( "side_channels=none" ) ;
361+ return lines ;
362+ }
363+
308364function renderPlatform ( platform : Record < string , string > ) : string {
309365 return Object . entries ( platform )
310366 . filter ( ( [ , value ] ) => value . trim ( ) . length > 0 )
0 commit comments