File size: 3,981 Bytes
1a343cd | 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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | export type BusReceipt = {
id: string;
eventType: string;
subject: string;
source: 'weed-sim' | 'agent' | 'system';
createdAt: string;
payload: Record<string, unknown>;
};
export type BusSignal = {
schema: 'observer_bus.signal/v1';
id: string;
lane: 'continuity' | 'repo' | 'tests' | 'filesystem' | 'runtime' | 'space' | 'security' | 'workflow' | 'custom' | 'receipt';
severity: 'info' | 'warn' | 'error';
priority: number;
title: string;
message: string;
timestamp: string;
route: {
command: string;
path: string;
method: 'GET' | 'POST';
};
ack: {
state: 'new' | 'acknowledged';
updatedAt: string | null;
note: string | null;
};
detail: Record<string, unknown>;
};
export type BusInbox = {
schema: 'observer_bus.signal_inbox/v1';
count: number;
lanes: string[];
task_list: Array<{
rank: number;
priority: number;
lane: string;
title: string;
command: string;
path: string;
why: string;
}>;
signals: BusSignal[];
notifications: BusSignal[];
};
export const WEED_SIM_FACILITIES = [
{ key: 'weedsim.inventory', label: 'Inventory', method: 'GET', path: '/api/inventory', risk: 'inspect' },
{ key: 'weedsim.load_starters', label: 'Load Starters', method: 'POST', path: '/api/inventory/starter', risk: 'mutating' },
{ key: 'weedsim.grow', label: 'Grow', method: 'POST', path: '/api/seed/{id}/grow', risk: 'mutating' },
{ key: 'weedsim.breed', label: 'Breed', method: 'POST', path: '/api/breed', risk: 'mutating' },
{ key: 'weedsim.clone', label: 'Clone', method: 'POST', path: '/api/clone', risk: 'mutating' },
{ key: 'weedsim.germplasm', label: 'Germplasm', method: 'GET', path: '/api/lab/germplasm', risk: 'inspect' },
{ key: 'weedsim.predict_cross', label: 'Predict Cross', method: 'POST', path: '/api/lab/predict-cross', risk: 'inspect' },
{ key: 'weedsim.newick', label: 'Newick Export', method: 'GET', path: '/api/lab/newick', risk: 'inspect' },
{ key: 'weedsim.agent_link', label: 'Agent Control', method: 'POST', path: '/api/agent-link/call', risk: 'scoped' },
{ key: 'weedsim.market.listings', label: 'Clone Exchange Listings', method: 'GET', path: '/api/market/listings', risk: 'inspect' },
{ key: 'weedsim.market.requests', label: 'Genetics Requests', method: 'GET', path: '/api/market/requests', risk: 'inspect' },
{ key: 'weedsim.market.request', label: 'Create Genetics Request', method: 'POST', path: '/api/market/requests', risk: 'mutating' },
{ key: 'weedsim.market.offer', label: 'Clone Exchange Offer', method: 'POST', path: '/api/market/offers', risk: 'escrow' },
{ key: 'weedsim.passport', label: 'Seed Passport', method: 'GET', path: '/api/passport/{seedId}', risk: 'inspect' },
{ key: 'weedsim.leaderboard', label: 'Leaderboard', method: 'GET', path: '/api/leaderboard', risk: 'inspect' },
] as const;
export function signalFromReceipt(receipt: BusReceipt): BusSignal {
return {
schema: 'observer_bus.signal/v1',
id: `sig_${receipt.id}`,
lane: 'receipt',
severity: 'info',
priority: 30,
title: `Receipt: ${receipt.eventType}`,
message: receipt.subject,
timestamp: receipt.createdAt,
route: {
command: 'receipts',
path: '/api/bus/receipts',
method: 'GET',
},
ack: {
state: 'new',
updatedAt: null,
note: null,
},
detail: receipt.payload,
};
}
export function inboxFromReceipts(receipts: BusReceipt[]): BusInbox {
const signals = receipts.slice(0, 20).map(signalFromReceipt);
return {
schema: 'observer_bus.signal_inbox/v1',
count: signals.length,
lanes: [...new Set(signals.map((signal) => signal.lane))],
task_list: signals.map((signal, index) => ({
rank: index + 1,
priority: signal.priority,
lane: signal.lane,
title: signal.title,
command: signal.route.command,
path: signal.route.path,
why: signal.message,
})),
signals,
notifications: signals,
};
}
|