Core tests / core (push) Successful in 9m57s
Full verification / application (push) Failing after 5m16s
Full verification / local-brain (push) Failing after 6m15s
Realm simulation / simulated-live-world (push) Failing after 5m32s
WoW integration lab / real-worldserver (push) Canceled after 17m23s
Source branch: feature/ai-brain-router Source commit: c2a09e0460465201a58aaab56c71424e9a96405e
71 lines
2.5 KiB
TypeScript
71 lines
2.5 KiB
TypeScript
import { env } from 'cloudflare:workers';
|
|
import { recentAleCommands,recentAleEvents } from '@/core/ale-store';
|
|
|
|
type SafeWorldEvent={
|
|
id:number;
|
|
at:string;
|
|
kind:string;
|
|
name?:string;
|
|
zone?:string;
|
|
level?:number;
|
|
isBot?:boolean;
|
|
};
|
|
|
|
function safeEvent(event:{id:number;at:string;kind:string;payload:unknown}):SafeWorldEvent{
|
|
const payload=(event.payload&&typeof event.payload==='object'?event.payload:{}) as Record<string,unknown>;
|
|
const out:SafeWorldEvent={id:event.id,at:event.at,kind:event.kind};
|
|
if(typeof payload.name==='string')out.name=payload.name.slice(0,40);
|
|
const zone=typeof payload.zoneName==='string'?payload.zoneName:typeof payload.zone==='string'?payload.zone:undefined;
|
|
if(zone)out.zone=zone.slice(0,120);
|
|
if(typeof payload.level==='number'&&Number.isFinite(payload.level))out.level=payload.level;
|
|
if(typeof payload.isBot==='boolean')out.isBot=payload.isBot;
|
|
return out;
|
|
}
|
|
|
|
export async function GET(){
|
|
try{
|
|
const [events,commands]=await Promise.all([
|
|
recentAleEvents(env.DB!,80),
|
|
recentAleCommands(env.DB!,30)
|
|
]);
|
|
const newest=events[0];
|
|
const now=Date.now();
|
|
const lastEventAt=newest?.at??null;
|
|
const ageMs=lastEventAt?Math.max(0,now-Date.parse(lastEventAt)):null;
|
|
const recentWindow=events.filter(e=>now-Date.parse(e.at)<5*60_000);
|
|
return Response.json({
|
|
ok:true,
|
|
ale:{
|
|
lastEventAt,
|
|
ageMs,
|
|
activeRecently:recentWindow.length>0,
|
|
bridgeReady:events.some(e=>e.kind==='bridge.ready')
|
|
},
|
|
playerbots:{
|
|
observedBots:new Set(recentWindow.flatMap(e=>{
|
|
const p=(e.payload&&typeof e.payload==='object'?e.payload:{}) as Record<string,unknown>;
|
|
if(p.isBot!==true)return [];
|
|
if(typeof p.characterGuid==='number')return [`guid:${p.characterGuid}`];
|
|
if(typeof p.name==='string'&&p.name.trim())return [`name:${p.name.toLowerCase()}`];
|
|
return [];
|
|
})).size
|
|
},
|
|
commands:{
|
|
pending:commands.filter(c=>c.status==='pending').length,
|
|
dispatched:commands.filter(c=>c.status==='dispatched').length,
|
|
completed:commands.filter(c=>c.status==='completed').length,
|
|
failed:commands.filter(c=>c.status==='failed').length
|
|
},
|
|
events:events.slice(0,30).map(safeEvent)
|
|
},{headers:{'Cache-Control':'no-store'}});
|
|
}catch{
|
|
return Response.json({
|
|
ok:false,
|
|
ale:{lastEventAt:null,ageMs:null,activeRecently:false,bridgeReady:false},
|
|
playerbots:{observedBots:0},
|
|
commands:{pending:0,dispatched:0,completed:0,failed:0},
|
|
events:[]
|
|
},{status:200,headers:{'Cache-Control':'no-store'}});
|
|
}
|
|
}
|