53 lines
3.7 KiB
JavaScript
53 lines
3.7 KiB
JavaScript
// Live model/Skill readiness only. Never uploads a reference or submits H3.
|
|
import assert from 'node:assert/strict';
|
|
const base='http://127.0.0.1:5173';
|
|
const abort=new AbortController();
|
|
async function api(path,method='GET',body){
|
|
const response=await fetch(base+path,{method,redirect:'error',signal:AbortSignal.timeout(20000),headers:{Origin:base,...(body?{'Content-Type':'application/json'}:{})},...(body?{body:JSON.stringify(body)}:{})});
|
|
assert(response.ok,`${method} ${path}: HTTP ${response.status}`);
|
|
return response.json();
|
|
}
|
|
let sessionId;
|
|
try {
|
|
const catalog=await api('/api/skills');
|
|
assert(catalog.skills.some(skill=>skill.name==='swads-image-to-video'),'New Skill missing from live catalog');
|
|
const history=await api('/api/image-video/tasks');
|
|
console.log(JSON.stringify({stage:'catalog-and-history',skillFound:true,historyAvailable:history!==undefined,remoteMutation:false}));
|
|
({sessionId}=await api('/api/sessions','POST',{}));
|
|
const stream=await fetch(`${base}/api/sessions/${sessionId}/events`,{signal:abort.signal});
|
|
assert(stream.ok&&stream.body,'SSE unavailable');
|
|
const reader=stream.body.getReader();
|
|
const sent=await api(`/api/sessions/${sessionId}/messages`,'POST',{text:'仅做 swads-image-to-video 接入只读检查:完整读取该 Skill 的 SKILL.md 和 references/swads.md。然后简短说明它不需要 CMS,以及必须分别批准参考图外传和 H3 生成。不要调用任何 CMS 工具,不读取图片或私人业务数据,不上传、不入库、不生成、不写文件。',attachmentIds:[]});
|
|
const timer=setTimeout(()=>abort.abort(),150000);
|
|
let buffer='';const decoder=new TextDecoder();let loaded=false;let answer=false;let referenceRead=false;let done=false;const referenceCalls=new Set();
|
|
try {
|
|
while(!done){
|
|
const chunk=await reader.read();assert(!chunk.done,'Unexpected SSE end');buffer+=decoder.decode(chunk.value,{stream:true});
|
|
let boundary;
|
|
while((boundary=buffer.indexOf('\n\n'))!==-1){
|
|
const frame=buffer.slice(0,boundary);buffer=buffer.slice(boundary+2);
|
|
const data=frame.split('\n').find(line=>line.startsWith('data: '))?.slice(6);if(!data)continue;
|
|
const event=JSON.parse(data);if(event.runId!==sent.runId)continue;
|
|
assert(event.type!=='approval.required','Unexpected external/mutating action request');
|
|
if(event.type==='tool.requested'){
|
|
assert(['read','ls','find','grep'].includes(event.payload.toolName),'Unexpected business tool requested');
|
|
if(event.payload.toolName==='read'&&JSON.stringify(event.payload.arguments).includes('references/swads.md'))referenceCalls.add(event.payload.toolCallId);
|
|
}
|
|
if(event.type==='skill.loaded')loaded=true;
|
|
if(event.type==='tool.completed'&&referenceCalls.has(event.payload.toolCallId))referenceRead=true;
|
|
if(event.type==='assistant.delta'&&event.payload.delta?.trim())answer=true;
|
|
if(['run.completed','run.failed','run.cancelled'].includes(event.type)){
|
|
console.log(JSON.stringify({stage:'model-skill',terminal:event.type,skillLoaded:loaded,referenceRead,answerReceived:answer,remoteMutation:false}));
|
|
assert(event.type==='run.completed');done=true;
|
|
}
|
|
}
|
|
}
|
|
assert(loaded&&referenceRead&&answer,'Skill/read/answer evidence incomplete');
|
|
}finally{clearTimeout(timer);abort.abort();}
|
|
console.log(JSON.stringify({result:'PASS',scope:'live Skill reading and local history only',h3GenerationVerified:false}));
|
|
}catch(error){console.error(JSON.stringify({result:'FAIL',message:String(error.message).slice(0,300)}));process.exitCode=1;}
|
|
finally{
|
|
abort.abort();
|
|
if(sessionId){await api(`/api/sessions/${sessionId}/cancel`,'POST',{}).catch(()=>{});await api(`/api/sessions/${sessionId}`,'DELETE').catch(()=>{});}
|
|
}
|