PageSourceSearch

https://embed-goodfire-attr-graph.netlify.app/attribution_graph/init-cg-feature-detail.js

js embed-goodfire-attr-graph.netlify.app collected 2026-10-03 10:41:49 UTC 6,173 bytes, 161 lines download raw bytes

1window.initCgFeatureDetail = async function({visState, renderAll, data, cgSel}){
2  var sel = cgSel.select('.feature-detail').html('')
3  if (!sel.node()) return
4
5  // var headerSel = sel.append('div.feature-header')
6  var logitsSel = sel.append('div.logits-container')
7  var examplesSel = sel.append('div.feature-examples-container')
8  var featureExamples = await window.initFeatureExamples({
9    containerSel: examplesSel,
10    showLogits: true,
11    // showLogits: !data.nodes.some(d => d.top_logit_effects) // we show logits ourselves frozen above the feature vis, don't also show it inside
12  })
13
14  let editOpen = false;
15
16  // throttle to prevent lag when mousing over
17  var renderFeatureExamples = util.throttleDebounce(featureExamples.renderFeature, 100)
18
19  function renderFeatureDetail() {
20    logitsSel.html('').st({display:''})
21
22    // display hovered then clicked nodes, with fallbacks for supernode
23    var d = null
24    // var d = data.nodes.find(e => e.nodeId === visState.hoveredNodeId)
25    if (!d) d = data.nodes.find(e => e.nodeId === visState.clickedId)
26    if (!d){
27      var featureId = visState.hoveredId
28      if (!featureId || featureId.includes('supernode')){
29        // headerSel.html('')
30        //   .append('div.no-selected-feature').text("Click or hover to see a feature's examples")
31        examplesSel.st({opacity: 0})
32        return
33      } 
34      return
35    }
36    
37    var label = d.isTmpFeature ? d.featureId : 
38      visState.isHideLayer ? `#F${d.featureIndex}` : 
39      `${utilCg.layerLocationLabel(d.layer, d.probe_location_idx)}/${d.featureIndex}`
40
41    if (d.isError || d.feature_type == 'embedding' || d.feature_type == 'logit'){
42      if (d.isError) addLogits(d)
43      if (d.feature_type=='logit') addEmbeddings(d)
44
45      // headerSel.html('').append('div.header-top-row').append('div.feature-title')
46      //   .text(d.ppClerp)
47      examplesSel.st({opacity: 0})
48    } else if (d.feature_type == 'cross layer transcoder') {
49      addLogits(d)
50      addEmbeddings(d)
51      // var headerTopRowSel = headerSel.html('').append('div.header-top-row')
52      // headerTopRowSel.append('div.feature-title')
53      //   .html(`Feature&nbsp;<a style="color: inherit;" href="${d.url}" target="_blank">${label}</a>`)
54
55      // headerTopRowSel.append('div.pp-clerp')
56      //   .text(d.ppClerp)
57      //   .at({title: d.ppClerp})
58
59      if (visState.isEditMode && false){
60        headerTopRowSel.append('button.edit-clerp-button')
61          .text('Edit')
62          .on('click', toggleEdit)
63  
64        function toggleEdit() {
65          editOpen = !editOpen;
66          hClerpEditSel.st({display: editOpen ? 'flex' : 'none'})
67          if (editOpen) {
68            headerSel.select('input').node()?.focus();
69          }
70        }
71  
72        const hClerpEditSel = headerSel.append('div.clerp-edit')
73          .st({ display: editOpen ? 'flex' : 'none' });
74  
75        const hClerpSel = hClerpEditSel.append('div')
76          .st({ display: 'flex' });
77        hClerpSel.append('div')
78          .st({flex: '0 0 50px'})
79          .text(`🧑💻`);
80        hClerpSel.append('input').data([d])
81          .at({ value: d.localClerp })
82          .st({flex: '1 0 0', whiteSpace: 'normal', fontSize: 12})
83          .on('change', ev => renderAll.hClerpUpdate([d, ev.target.value]))
84  
85        const rClerpSel = hClerpEditSel.append('div')
86            .st({ display: 'flex' });
87          rClerpSel.append('div')
88            .st({flex: '0 0 50px'})
89            .text(`🧑☁️`);
90          rClerpSel.append('div')
91            .text(d.remoteClerp)
92            .st({flex: '1 0', whiteSpace: 'normal'})
93  
94        const clerpSel = hClerpEditSel.append('div')
95          .st({ display: 'flex' });
96        clerpSel.append('div')
97          .st({flex: '0 0 50px'})
98          .text(`🤖💬`);
99        clerpSel.append('div')
100          .text(d.clerp)
101          .st({ flex: '1 0', whiteSpace: 'normal' })
102      }
103
104      featureExamples.loadFeature(data.metadata.scan, d.featureIndex)
105      renderFeatureExamples(data.metadata.scan, d.featureIndex)
106      examplesSel.st({opacity: 1})
107    } else {
108      headerSel.html(`<b>${label}</b>`)
109      logitsSel.html('No logit data')
110      examplesSel.st({opacity: 0})
111    }
112
113    // add pinned/click state and toggle to feature-title
114    // headerSel.select('div.feature-title')
115    //   .classed('pinned', d.nodeId && visState.pinnedIds.includes(d.nodeId))
116    //   .classed('hovered', visState.clickedId == d.nodeId)
117    //   .on('click', ev => {
118    //     utilCg.clickFeature(visState, renderAll, d, ev.metaKey || ev.ctrlKey)
119
120    //     if (visState.clickedId) return
121    //     // double render to toggle on hoveredId, could expose more of utilCg.clickFeature to prevent
122    //     visState.hoveredId = d.featureId
123    //     renderAll.hoveredId()
124    //   })
125
126  }
127
128  function addLogits(d) {
129    return
130    if (!d || !d.top_logit_effects) return logitsSel.html('').st({display: 'none'})
131    // Add logit effects section
132    let logitRowContainerSel = logitsSel.st({display: ''})
133      .append('div.effects')
134      .appendMany('div.sign', [d.top_logit_effects, d.bottom_logit_effects].filter(d => d))
135    logitRowContainerSel.append('div.label').text((d, i) => i ? 'Bottom Outputs' : 'Top Outputs')
136    logitRowContainerSel.append('div.rows')
137      .appendMany('div.row', d => d)
138      .append('span.key').text(d => d)
139  }
140  function addEmbeddings(d) { 
141    return
142    // Add embedding effects section
143    if (d.top_embedding_effects || d.bottom_embedding_effects) {
144      let embeddingRowContainerSel = logitsSel
145        .append('div.effects')
146        .appendMany('div.sign', [d.top_embedding_effects, d.bottom_embedding_effects].filter(d => d))
147      embeddingRowContainerSel.append('div.label').text((d, i) => i ? 'Bottom Inputs' : 'Top Inputs')
148      embeddingRowContainerSel.append('div.rows').appendMany('div.row', d => d)
149        .append('span.key').text(d => d)
150    }
151  }
152
153  renderAll.hClerpUpdate.fns.push(renderFeatureDetail)
154  renderAll.clickedId.fns.push(renderFeatureDetail)
155  renderAll.hoveredId.fns.push(renderFeatureDetail)
156  renderAll.pinnedIds.fns.push(renderFeatureDetail)
157
158  renderFeatureDetail()
159}
160
161window.init?.()

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.