Spaces:
Running on Zero
Running on Zero
File size: 6,134 Bytes
adb939d 9f8666e adb939d 9f8666e adb939d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 'use strict';
// The browser-local agent surface delegates to the same guarded UI controllers.
// It intentionally exposes no job, credential, bucket, deletion or arbitrary-selector action.
(() => {
const q=id=>document.getElementById(id);
const sections=['drive','training','batch','editor'];
const controls={create_starter:'starter_create',inspect_selected_network:'editor_import'};
let toolSupport='unavailable',agentBusy=false;
const option=id=>{const node=q(id);return node?.selectedOptions?.[0]?.textContent?.trim()||null;};
function readState(){
const file=window.TrainingClient?.getSelectedNetwork?.();
return {
schema:'ald.agent-state',version:1,
section:document.querySelector('.tabs [aria-selected="true"]')?.dataset.tab||'drive',
network:{selected:!!file,name:file?(file.name||'Latest received result'):null},
track:option('trackPresetDrive'),compute:option('backend'),
run:{enabled:!!q('run')&&!q('run').disabled,label:q('run')?.textContent.trim()||null,status:q('status')?.textContent.trim()||null},
editor:{state:q('editor_status')?.dataset.state||'idle',message:q('editor_status')?.textContent.trim()||null,network:q('editor_metadata')?.textContent.trim()||null},
busy:agentBusy||!!window.TrainingClient?.isBusy?.(),
webmcp:toolSupport,
actions:{get_state:true,open_section:true,create_starter:!agentBusy&&!!q('starter_create')&&!q('starter_create').disabled,inspect_selected_network:!agentBusy&&!!q('editor_import')&&!q('editor_import').disabled}
};
}
function render(){const node=q('agent_state');if(node){const text=JSON.stringify(readState(),null,2);if(node.textContent!==text)node.textContent=text;}}
function exact(input,keys){
if(!input||typeof input!=='object'||Array.isArray(input)||Object.keys(input).some(key=>!keys.includes(key)))throw Error('Invalid action arguments');
}
async function act(action,input={}){
exact(input,action==='open_section'?['section']:[]);
if(action==='get_state')return readState();
if(action==='open_section'){
if(!sections.includes(input.section))throw Error('Choose drive, training, batch or editor');
window.LabNavigation.openSection(input.section);return readState();
}
const id=controls[action];if(!id)throw Error('Unknown local action');
if(agentBusy||window.TrainingClient?.isBusy?.()||!q(id)||q(id).disabled)throw Error('This control is unavailable; read the current state first');
agentBusy=true;render();
try{
if(action==='create_starter'){
window.LabNavigation.openSection('drive');
await window.TrainingClient.createStarter();
}else{
window.LabNavigation.openSection('editor');
await window.NetworkEditorUI.inspectSelected();
}
}finally{agentBusy=false;render();}
return readState();
}
window.ALDLabAgent=Object.freeze({version:1,readState,act});
// Keep fallback state visible and current without inspecting cookies or tokens.
let scheduled=false;
const schedule=()=>{if(scheduled)return;scheduled=true;queueMicrotask(()=>{scheduled=false;render();});};
const observer=new MutationObserver(records=>{
if(records.some(record=>!q('agent_state')?.contains(record.target)&&record.target!==q('agent_state')))schedule();
});
observer.observe(document.body,{subtree:true,childList:true,characterData:true,attributes:true,attributeFilter:['disabled','aria-selected','data-state']});
document.addEventListener('change',schedule);document.addEventListener('input',schedule);
window.addEventListener('ald:editor-status',schedule);window.addEventListener('ald:section-change',schedule);
const definitions=[
{name:'ald_get_state',title:'Read Driving Around state',description:'Read the current tab, selected driver name, track, compute choice, readiness and visible status. No credentials, weights or job identifiers are returned.',inputSchema:{type:'object',properties:{},additionalProperties:false},annotations:{readOnlyHint:true,untrustedContentHint:true},execute:async input=>JSON.stringify(await act('get_state',input))},
{name:'ald_open_section',title:'Open a Driving Around section',description:'Open a local lab tab and bring its heading into view. Does not start a job or save data.',inputSchema:{type:'object',properties:{section:{type:'string',enum:sections}},required:['section'],additionalProperties:false},execute:async input=>JSON.stringify(await act('open_section',input))},
{name:'ald_create_starter',title:'Create a local starter driver',description:'Create and select a small starter for the current Starter car. Uses the same UI confirmation when replacing a selection. Does not train, upload or save data.',inputSchema:{type:'object',properties:{},additionalProperties:false},execute:async input=>JSON.stringify(await act('create_starter',input))},
{name:'ald_inspect_selected_network',title:'Inspect the selected Driving Around driver',description:'Open the editor and inspect the active driver or chosen editor file. Read the returned editor state for success or error. Does not change the active driver or original weights.',inputSchema:{type:'object',properties:{},additionalProperties:false},annotations:{untrustedContentHint:true},execute:async input=>JSON.stringify(await act('inspect_selected_network',input))}
];
async function register(){
const context=document.modelContext;
if(typeof context?.registerTool!=='function'){
q('agent_tools_status').textContent='Browser tools are unavailable here. Use the action manifest, stable controls and current state below.';
render();return;
}
try{
for(const tool of definitions)await context.registerTool(tool);
toolSupport='registered';
q('agent_tools_status').textContent='Four browser-local WebMCP tools registered. The same actions remain available through the visible controls.';
}catch{
toolSupport='registration-failed';
q('agent_tools_status').textContent='Browser tool registration was incomplete. Use the action manifest and visible controls.';
}
render();
}
render();register();
})();
|