@wenathlan/extension 1.1.57 → 1.1.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/dist/agentmailbox.d.ts +42 -0
- package/dist/agentmailbox.d.ts.map +1 -0
- package/dist/blackboard.d.ts +55 -0
- package/dist/blackboard.d.ts.map +1 -0
- package/dist/coordination.d.ts +139 -0
- package/dist/coordination.d.ts.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4467 -3447
- package/dist/index.js.map +4 -4
- package/dist/memory.d.ts +111 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/multiagent.d.ts +151 -0
- package/dist/multiagent.d.ts.map +1 -0
- package/dist/orchestration.d.ts +174 -0
- package/dist/orchestration.d.ts.map +1 -0
- package/dist/policy.d.ts +80 -1
- package/dist/policy.d.ts.map +1 -1
- package/dist/protocol.d.ts +93 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/taskqueue.d.ts +97 -0
- package/dist/taskqueue.d.ts.map +1 -0
- package/dist/types.d.ts +460 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/extension/dist/background.js +5449 -3874
- package/extension/dist/background.js.map +4 -4
- package/extension/dist/manifest.json +1 -1
- package/extension/dist/pagebridge.js.map +1 -1
- package/extension/dist/popup.html +1 -1
- package/extension/dist/popup.js +12 -0
- package/extension/dist/popup.js.map +2 -2
- package/extension/dist/sidepanel.html +1 -1
- package/extension/dist/sidepanel.js +889 -0
- package/extension/dist/sidepanel.js.map +3 -3
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
|
@@ -394,6 +394,7 @@ var workfloweditorroot = document.querySelector("#workfloweditor");
|
|
|
394
394
|
var triggersroot = document.querySelector("#triggers");
|
|
395
395
|
var agentprotocolroot = document.querySelector("#agentprotocol");
|
|
396
396
|
var modelsroot = document.querySelector("#models");
|
|
397
|
+
var agentsroot = document.querySelector("#agents");
|
|
397
398
|
var commandinput = document.querySelector("#command");
|
|
398
399
|
var commandbutton = document.querySelector("#commandsend");
|
|
399
400
|
var intentbadge = document.querySelector("#intentbadge");
|
|
@@ -2881,6 +2882,7 @@ async function refresh() {
|
|
|
2881
2882
|
rendertriggers(context);
|
|
2882
2883
|
renderagentprotocol(context);
|
|
2883
2884
|
rendermodels(context);
|
|
2885
|
+
renderagents(context);
|
|
2884
2886
|
renderconsolediff();
|
|
2885
2887
|
renderaudit(context.audit);
|
|
2886
2888
|
rendercapabilities(context.capabilities);
|
|
@@ -5541,4 +5543,891 @@ function rendermodels(context) {
|
|
|
5541
5543
|
}
|
|
5542
5544
|
modelsroot.append(guardbox);
|
|
5543
5545
|
}
|
|
5546
|
+
function renderagents(context) {
|
|
5547
|
+
if (!agentsroot) return;
|
|
5548
|
+
agentsroot.replaceChildren();
|
|
5549
|
+
const swarm = context.swarm;
|
|
5550
|
+
if (!swarm) {
|
|
5551
|
+
const empty = document.createElement("p");
|
|
5552
|
+
empty.textContent = "The swarm state is unknown.";
|
|
5553
|
+
agentsroot.append(empty);
|
|
5554
|
+
return;
|
|
5555
|
+
}
|
|
5556
|
+
const head = document.createElement("p");
|
|
5557
|
+
head.textContent = `${swarm.overview.agents} agent${swarm.overview.agents === 1 ? "" : "s"} (${swarm.overview.active} active, ${swarm.overview.paused} paused, ${swarm.overview.stopped} stopped) \xB7 ${swarm.overview.tasks} task${swarm.overview.tasks === 1 ? "" : "s"} (${swarm.overview.claimed} claimed, ${swarm.overview.queued} queued, ${swarm.overview.done} done) \xB7 ${swarm.overview.messages} message${swarm.overview.messages === 1 ? "" : "s"} with ${swarm.overview.unread} unread \xB7 queue policy ${swarm.queue.completionpolicy}${swarm.queue.complete ? " \xB7 queue complete" : ""}.`;
|
|
5558
|
+
agentsroot.append(head);
|
|
5559
|
+
const switchbox = document.createElement("div");
|
|
5560
|
+
switchbox.className = "actions";
|
|
5561
|
+
if (swarm.killswitch.engaged) {
|
|
5562
|
+
const state = document.createElement("span");
|
|
5563
|
+
state.className = "muted";
|
|
5564
|
+
state.textContent = `Killswitch engaged${swarm.killswitch.reason !== void 0 ? `: ${swarm.killswitch.reason}` : ""}; every agent halted.`;
|
|
5565
|
+
switchbox.append(state, " ", button("Disarm killswitch", async () => {
|
|
5566
|
+
await request({ kind: "swarmagent", disarm: true });
|
|
5567
|
+
status("The killswitch disarmed; the stopped agents stay stopped until resumed.");
|
|
5568
|
+
await refresh();
|
|
5569
|
+
}));
|
|
5570
|
+
} else {
|
|
5571
|
+
switchbox.append(button("Halt every agent (killswitch)", async () => {
|
|
5572
|
+
if (window.confirm("Halt every agent of the swarm at once?")) {
|
|
5573
|
+
await request({ kind: "swarmagent", killall: true, reason: "The user halted the swarm from the panel." });
|
|
5574
|
+
status("The killswitch engaged: every agent halted at once and the claims returned to the queue.");
|
|
5575
|
+
await refresh();
|
|
5576
|
+
}
|
|
5577
|
+
}));
|
|
5578
|
+
}
|
|
5579
|
+
agentsroot.append(switchbox);
|
|
5580
|
+
const agentsbox = document.createElement("details");
|
|
5581
|
+
agentsbox.className = "sessiongroup";
|
|
5582
|
+
agentsbox.open = true;
|
|
5583
|
+
const agentsummary = document.createElement("summary");
|
|
5584
|
+
agentsummary.textContent = `Agent cards (${swarm.agents.length})`;
|
|
5585
|
+
agentsbox.append(agentsummary);
|
|
5586
|
+
for (const agent of swarm.agents) {
|
|
5587
|
+
const row = document.createElement("div");
|
|
5588
|
+
row.className = "sessionrow";
|
|
5589
|
+
const info = document.createElement("p");
|
|
5590
|
+
const budgettext = agent.budget === void 0 ? "no ceiling" : [agent.budget.maxtokens !== void 0 ? `${agent.usage?.tokens ?? 0}/${agent.budget.maxtokens} tokens` : "", agent.budget.maxcost !== void 0 ? `${agent.usage?.cost ?? 0}/${agent.budget.maxcost} ${agent.budget.currency ?? ""}` : "", agent.budget.maxsteps !== void 0 ? `${agent.usage?.steps ?? 0}/${agent.budget.maxsteps} steps` : ""].filter((part) => part !== "").join(", ") || "no ceiling set";
|
|
5591
|
+
info.textContent = `${agent.name} \xB7 ${agent.role} \xB7 ${agent.state}${agent.tabid !== void 0 ? ` \xB7 tab ${agent.tabid}` : ""}${agent.parentid !== void 0 ? ` \xB7 sub of ${agent.parentid} at depth ${agent.depth}` : ""}${agent.currenttask !== void 0 ? ` \xB7 working: ${agent.currenttask}` : " \xB7 idle"} \xB7 budget ${budgettext}${agent.heartbeatat !== void 0 ? ` \xB7 heartbeat ${new Date(agent.heartbeatat).toLocaleTimeString()}` : ""}${agent.unread > 0 ? ` \xB7 ${agent.unread} unread` : ""}${agent.reviewstatus !== void 0 ? ` \xB7 review: ${agent.reviewstatus}` : ""}${agent.handoffarrows.length > 0 ? ` \xB7 handoffs: ${agent.handoffarrows.join(", ")}` : ""}.`;
|
|
5592
|
+
row.append(info);
|
|
5593
|
+
const actions = document.createElement("div");
|
|
5594
|
+
actions.className = "actions";
|
|
5595
|
+
actions.append(button("Pause", async () => {
|
|
5596
|
+
await request({ kind: "swarmagent", agentid: agent.id, action: "pause" });
|
|
5597
|
+
status(`Paused the agent ${agent.name}; the others keep running.`);
|
|
5598
|
+
await refresh();
|
|
5599
|
+
}), " ", button("Resume", async () => {
|
|
5600
|
+
await request({ kind: "swarmagent", agentid: agent.id, action: "resume" });
|
|
5601
|
+
status(`Resumed the agent ${agent.name}.`);
|
|
5602
|
+
await refresh();
|
|
5603
|
+
}), " ", button("Stop", async () => {
|
|
5604
|
+
await request({ kind: "swarmagent", agentid: agent.id, action: "stop" });
|
|
5605
|
+
status(`Stopped the agent ${agent.name}.`);
|
|
5606
|
+
await refresh();
|
|
5607
|
+
}), " ", button("Claim task", async () => {
|
|
5608
|
+
await request({ kind: "swarmqueue", agentid: agent.id, claim: true });
|
|
5609
|
+
status(`The agent ${agent.name} claimed the highest priority task; the proposal still passes the plan review.`);
|
|
5610
|
+
await refresh();
|
|
5611
|
+
}), " ", button("Heartbeat", async () => {
|
|
5612
|
+
await request({ kind: "swarmagent", agentid: agent.id, heartbeat: true });
|
|
5613
|
+
status(`The agent ${agent.name} refreshed its heartbeat.`);
|
|
5614
|
+
await refresh();
|
|
5615
|
+
}));
|
|
5616
|
+
const budgetrow = document.createElement("div");
|
|
5617
|
+
budgetrow.className = "actions";
|
|
5618
|
+
const tokensinput = document.createElement("input");
|
|
5619
|
+
tokensinput.placeholder = "token ceiling";
|
|
5620
|
+
const costinput = document.createElement("input");
|
|
5621
|
+
costinput.placeholder = "cost ceiling";
|
|
5622
|
+
const stepsinput = document.createElement("input");
|
|
5623
|
+
stepsinput.placeholder = "step ceiling";
|
|
5624
|
+
const currencyinput = document.createElement("input");
|
|
5625
|
+
currencyinput.placeholder = "currency";
|
|
5626
|
+
budgetrow.append(tokensinput, " ", costinput, " ", currencyinput, " ", stepsinput, " ", button("Set budget", async () => {
|
|
5627
|
+
await request({ kind: "swarmagent", agentid: agent.id, budget: { ...tokensinput.value.trim() !== "" ? { maxtokens: Number(tokensinput.value) } : {}, ...costinput.value.trim() !== "" ? { maxcost: Number(costinput.value) } : {}, ...stepsinput.value.trim() !== "" ? { maxsteps: Number(stepsinput.value) } : {}, ...currencyinput.value.trim() !== "" ? { currency: currencyinput.value.trim() } : {} } });
|
|
5628
|
+
status(`Saved the budget of the agent ${agent.name}.`);
|
|
5629
|
+
await refresh();
|
|
5630
|
+
}));
|
|
5631
|
+
row.append(actions, budgetrow);
|
|
5632
|
+
agentsbox.append(row);
|
|
5633
|
+
}
|
|
5634
|
+
const addrow = document.createElement("div");
|
|
5635
|
+
addrow.className = "actions";
|
|
5636
|
+
const nameinput = document.createElement("input");
|
|
5637
|
+
nameinput.placeholder = "new agent name";
|
|
5638
|
+
const roleselect = document.createElement("select");
|
|
5639
|
+
for (const role of ["worker", "planner", "observer", "critic", "verifier"]) {
|
|
5640
|
+
const option = document.createElement("option");
|
|
5641
|
+
option.value = role;
|
|
5642
|
+
option.textContent = role;
|
|
5643
|
+
roleselect.append(option);
|
|
5644
|
+
}
|
|
5645
|
+
const customrole = document.createElement("input");
|
|
5646
|
+
customrole.placeholder = "custom role";
|
|
5647
|
+
const tabinput = document.createElement("input");
|
|
5648
|
+
tabinput.placeholder = "tab id";
|
|
5649
|
+
addrow.append(nameinput, " ", roleselect, " ", customrole, " ", tabinput, " ", button("Register agent", async () => {
|
|
5650
|
+
await request({ kind: "swarmagent", register: { name: nameinput.value, role: customrole.value.trim() !== "" ? customrole.value.trim() : roleselect.value, ...tabinput.value.trim() !== "" ? { tabid: Number(tabinput.value) } : {} } });
|
|
5651
|
+
status(`Registered the agent ${nameinput.value}; one tab holds at most one agent.`);
|
|
5652
|
+
await refresh();
|
|
5653
|
+
}));
|
|
5654
|
+
agentsbox.append(addrow);
|
|
5655
|
+
const spawnrow = document.createElement("div");
|
|
5656
|
+
spawnrow.className = "actions";
|
|
5657
|
+
const parentselect = document.createElement("select");
|
|
5658
|
+
for (const agent of swarm.agents) {
|
|
5659
|
+
const option = document.createElement("option");
|
|
5660
|
+
option.value = agent.id;
|
|
5661
|
+
option.textContent = agent.name;
|
|
5662
|
+
parentselect.append(option);
|
|
5663
|
+
}
|
|
5664
|
+
const spawnrole = document.createElement("select");
|
|
5665
|
+
for (const role of ["worker", "planner", "observer", "critic", "verifier"]) {
|
|
5666
|
+
const option = document.createElement("option");
|
|
5667
|
+
option.value = role;
|
|
5668
|
+
option.textContent = role;
|
|
5669
|
+
spawnrole.append(option);
|
|
5670
|
+
}
|
|
5671
|
+
const spawntask = document.createElement("input");
|
|
5672
|
+
spawntask.placeholder = "sub agent task";
|
|
5673
|
+
const spawndepth = document.createElement("input");
|
|
5674
|
+
spawndepth.placeholder = "depth";
|
|
5675
|
+
spawndepth.value = "1";
|
|
5676
|
+
const spawnname = document.createElement("input");
|
|
5677
|
+
spawnname.placeholder = "sub agent name";
|
|
5678
|
+
spawnrow.append(parentselect, " ", spawnrole, " ", spawntask, " ", spawndepth, " ", spawnname, " ", button("Spawn sub agent", async () => {
|
|
5679
|
+
await request({ kind: "swarmagent", spawn: { parentid: parentselect.value, role: spawnrole.value, task: spawntask.value, depth: Number(spawndepth.value || "1"), ...spawnname.value.trim() !== "" ? { name: spawnname.value } : {} } });
|
|
5680
|
+
status("Spawned the sub agent; the depth history records the recursion.");
|
|
5681
|
+
await refresh();
|
|
5682
|
+
}));
|
|
5683
|
+
agentsbox.append(spawnrow);
|
|
5684
|
+
if (swarm.spawns.length > 0) {
|
|
5685
|
+
const history = document.createElement("p");
|
|
5686
|
+
history.textContent = `Spawn history: ${swarm.spawns.slice(0, 5).map((record) => `${record.parentid} \u2192 ${record.childid} (${record.role}, depth ${record.depth})`).join("; ")}.`;
|
|
5687
|
+
agentsbox.append(history);
|
|
5688
|
+
}
|
|
5689
|
+
agentsroot.append(agentsbox);
|
|
5690
|
+
const queuebox = document.createElement("details");
|
|
5691
|
+
queuebox.className = "sessiongroup";
|
|
5692
|
+
queuebox.open = true;
|
|
5693
|
+
const queuesummary = document.createElement("summary");
|
|
5694
|
+
queuesummary.textContent = `Task queue (${swarm.queue.items.length})`;
|
|
5695
|
+
queuebox.append(queuesummary);
|
|
5696
|
+
for (const lane of swarm.queue.lanesreport) {
|
|
5697
|
+
const row = document.createElement("p");
|
|
5698
|
+
const claims = swarm.queue.claims.filter((claim) => swarm.queue.items.some((item) => item.id === claim.taskid && item.lane === lane.lane && item.state === "claimed"));
|
|
5699
|
+
row.textContent = `Lane ${lane.lane}: ${lane.queued} queued \xB7 ${lane.claimed} claimed \xB7 ${lane.done} done \xB7 ${lane.cancelled} cancelled${claims.length > 0 ? ` \xB7 held by ${claims.map((claim) => claim.agentid).join(", ")}` : ""}.`;
|
|
5700
|
+
queuebox.append(row);
|
|
5701
|
+
}
|
|
5702
|
+
const list = document.createElement("ol");
|
|
5703
|
+
list.className = "audit";
|
|
5704
|
+
for (const item of swarm.queue.items.slice(0, 12)) {
|
|
5705
|
+
const entry = document.createElement("li");
|
|
5706
|
+
entry.textContent = `${item.payload} \u2014 lane ${item.lane}, priority ${item.priority}, ${item.state}.`;
|
|
5707
|
+
const actions = document.createElement("div");
|
|
5708
|
+
actions.className = "actions";
|
|
5709
|
+
actions.append(button("Complete", async () => {
|
|
5710
|
+
await request({ kind: "swarmqueue", taskid: item.id, complete: true });
|
|
5711
|
+
status("The task completed and released its claim.");
|
|
5712
|
+
await refresh();
|
|
5713
|
+
}), " ", button("Cancel", async () => {
|
|
5714
|
+
await request({ kind: "swarmqueue", taskid: item.id, cancel: true });
|
|
5715
|
+
status("The task left the queue.");
|
|
5716
|
+
await refresh();
|
|
5717
|
+
}));
|
|
5718
|
+
entry.append(actions);
|
|
5719
|
+
list.append(entry);
|
|
5720
|
+
}
|
|
5721
|
+
queuebox.append(list);
|
|
5722
|
+
const enqueuerow = document.createElement("div");
|
|
5723
|
+
enqueuerow.className = "actions";
|
|
5724
|
+
const laneinput = document.createElement("input");
|
|
5725
|
+
laneinput.placeholder = "lane";
|
|
5726
|
+
const priorityinput = document.createElement("input");
|
|
5727
|
+
priorityinput.placeholder = "priority";
|
|
5728
|
+
const payloadinput = document.createElement("input");
|
|
5729
|
+
payloadinput.placeholder = "task in plain language";
|
|
5730
|
+
const lanesinput = document.createElement("input");
|
|
5731
|
+
lanesinput.placeholder = "configured lanes, comma separated";
|
|
5732
|
+
lanesinput.value = swarm.queue.lanes.join(", ");
|
|
5733
|
+
enqueuerow.append(laneinput, " ", priorityinput, " ", payloadinput, " ", button("Enqueue", async () => {
|
|
5734
|
+
await request({ kind: "swarmqueue", enqueue: { lane: laneinput.value, priority: Number(priorityinput.value || "0"), payload: payloadinput.value } });
|
|
5735
|
+
status("The task entered the lane; nothing runs before the plan review.");
|
|
5736
|
+
await refresh();
|
|
5737
|
+
}), " ", button("Requeue orphans", async () => {
|
|
5738
|
+
await request({ kind: "swarmqueue", requeue: true });
|
|
5739
|
+
status("The requeue pass returned the orphaned tasks to their lanes.");
|
|
5740
|
+
await refresh();
|
|
5741
|
+
}), " ", button("Save lanes", async () => {
|
|
5742
|
+
await request({ kind: "swarmqueue", lanes: lanesinput.value.split(",").map((lane) => lane.trim()).filter((lane) => lane !== "") });
|
|
5743
|
+
status("Saved the configured lanes.");
|
|
5744
|
+
await refresh();
|
|
5745
|
+
}));
|
|
5746
|
+
queuebox.append(enqueuerow);
|
|
5747
|
+
agentsroot.append(queuebox);
|
|
5748
|
+
const mailboxbox = document.createElement("details");
|
|
5749
|
+
mailboxbox.className = "sessiongroup";
|
|
5750
|
+
const mailboxsummary = document.createElement("summary");
|
|
5751
|
+
mailboxsummary.textContent = `Mailboxes (${swarm.mailboxes.length})`;
|
|
5752
|
+
mailboxbox.append(mailboxsummary);
|
|
5753
|
+
for (const mailbox of swarm.mailboxes) {
|
|
5754
|
+
if (mailbox.inbox.length === 0 && mailbox.outbox.length === 0) continue;
|
|
5755
|
+
const row = document.createElement("div");
|
|
5756
|
+
row.className = "sessionrow";
|
|
5757
|
+
const info = document.createElement("p");
|
|
5758
|
+
info.textContent = `Agent ${mailbox.agentid}: ${mailbox.inbox.length} in, ${mailbox.outbox.length} out, ${mailbox.unread} unread.`;
|
|
5759
|
+
row.append(info);
|
|
5760
|
+
const feed = document.createElement("ul");
|
|
5761
|
+
feed.className = "audit";
|
|
5762
|
+
for (const message of [...mailbox.inbox, ...mailbox.outbox].slice(0, 6)) {
|
|
5763
|
+
const entry = document.createElement("li");
|
|
5764
|
+
entry.textContent = `${message.senderid} \u2192 ${message.recipient} (${message.routing}): ${message.payload}`;
|
|
5765
|
+
feed.append(entry);
|
|
5766
|
+
}
|
|
5767
|
+
row.append(feed, button("Receive", async () => {
|
|
5768
|
+
await request({ kind: "swarmmailbox", agentid: mailbox.agentid, receive: true });
|
|
5769
|
+
status(`The agent ${mailbox.agentid} drained its inbox.`);
|
|
5770
|
+
await refresh();
|
|
5771
|
+
}));
|
|
5772
|
+
mailboxbox.append(row);
|
|
5773
|
+
}
|
|
5774
|
+
const composerow = document.createElement("div");
|
|
5775
|
+
composerow.className = "actions";
|
|
5776
|
+
const recipientselect = document.createElement("select");
|
|
5777
|
+
const broadcastoption = document.createElement("option");
|
|
5778
|
+
broadcastoption.value = "*";
|
|
5779
|
+
broadcastoption.textContent = "broadcast (every agent)";
|
|
5780
|
+
recipientselect.append(broadcastoption);
|
|
5781
|
+
for (const agent of swarm.agents) {
|
|
5782
|
+
const option = document.createElement("option");
|
|
5783
|
+
option.value = agent.id;
|
|
5784
|
+
option.textContent = `${agent.name} (${agent.id})`;
|
|
5785
|
+
recipientselect.append(option);
|
|
5786
|
+
}
|
|
5787
|
+
const routingselect = document.createElement("select");
|
|
5788
|
+
for (const routing of ["direct", "broadcast", "role"]) {
|
|
5789
|
+
const option = document.createElement("option");
|
|
5790
|
+
option.value = routing;
|
|
5791
|
+
option.textContent = routing;
|
|
5792
|
+
routingselect.append(option);
|
|
5793
|
+
}
|
|
5794
|
+
const messageinput = document.createElement("input");
|
|
5795
|
+
messageinput.placeholder = "message to the agents";
|
|
5796
|
+
composerow.append(recipientselect, " ", routingselect, " ", messageinput, " ", button("Send user message", async () => {
|
|
5797
|
+
await request({ kind: "swarmmailbox", send: { senderid: "user", recipient: recipientselect.value, routing: routingselect.value, payload: messageinput.value } });
|
|
5798
|
+
status("The user message was delivered to the swarm.");
|
|
5799
|
+
await refresh();
|
|
5800
|
+
}));
|
|
5801
|
+
mailboxbox.append(composerow);
|
|
5802
|
+
agentsroot.append(mailboxbox);
|
|
5803
|
+
const boardbox = document.createElement("details");
|
|
5804
|
+
boardbox.className = "sessiongroup";
|
|
5805
|
+
const boardsummary = document.createElement("summary");
|
|
5806
|
+
boardsummary.textContent = "Blackboard";
|
|
5807
|
+
boardbox.append(boardsummary);
|
|
5808
|
+
for (const section of swarm.blackboard.sections) {
|
|
5809
|
+
const row = document.createElement("p");
|
|
5810
|
+
row.textContent = `Section ${section.section}: ${section.entries} live entr${section.entries === 1 ? "y" : "ies"}${section.authors.length > 0 ? ` by ${section.authors.join(", ")}` : ""}${section.freshestat !== void 0 ? ` \xB7 freshest ${new Date(section.freshestat).toLocaleTimeString()}` : ""}.`;
|
|
5811
|
+
boardbox.append(row);
|
|
5812
|
+
}
|
|
5813
|
+
const entries = document.createElement("ol");
|
|
5814
|
+
entries.className = "audit";
|
|
5815
|
+
for (const entry of swarm.blackboard.entries.slice(0, 12)) {
|
|
5816
|
+
const item = document.createElement("li");
|
|
5817
|
+
item.textContent = `[${entry.section}] ${entry.key} = ${entry.value} \u2014 ${entry.author}, ${entry.consentclass}, posted ${new Date(entry.postedat).toLocaleTimeString()}.`;
|
|
5818
|
+
const actions = document.createElement("div");
|
|
5819
|
+
actions.className = "actions";
|
|
5820
|
+
actions.append(button("Retire", async () => {
|
|
5821
|
+
await request({ kind: "swarmblackboard", retire: entry.id });
|
|
5822
|
+
status(`Retired the entry ${entry.key}.`);
|
|
5823
|
+
await refresh();
|
|
5824
|
+
}));
|
|
5825
|
+
item.append(actions);
|
|
5826
|
+
entries.append(item);
|
|
5827
|
+
}
|
|
5828
|
+
boardbox.append(entries);
|
|
5829
|
+
const postrow = document.createElement("div");
|
|
5830
|
+
postrow.className = "actions";
|
|
5831
|
+
const keyinput = document.createElement("input");
|
|
5832
|
+
keyinput.placeholder = "key";
|
|
5833
|
+
const valueinput = document.createElement("input");
|
|
5834
|
+
valueinput.placeholder = "value";
|
|
5835
|
+
const sectionselect = document.createElement("select");
|
|
5836
|
+
for (const section of ["goals", "facts", "findings", "scratch"]) {
|
|
5837
|
+
const option = document.createElement("option");
|
|
5838
|
+
option.value = section;
|
|
5839
|
+
option.textContent = section;
|
|
5840
|
+
sectionselect.append(option);
|
|
5841
|
+
}
|
|
5842
|
+
const authorselect = document.createElement("select");
|
|
5843
|
+
const useroption = document.createElement("option");
|
|
5844
|
+
useroption.value = "user";
|
|
5845
|
+
useroption.textContent = "user";
|
|
5846
|
+
authorselect.append(useroption);
|
|
5847
|
+
for (const agent of swarm.agents) {
|
|
5848
|
+
const option = document.createElement("option");
|
|
5849
|
+
option.value = agent.id;
|
|
5850
|
+
option.textContent = agent.name;
|
|
5851
|
+
authorselect.append(option);
|
|
5852
|
+
}
|
|
5853
|
+
postrow.append(keyinput, " ", valueinput, " ", sectionselect, " ", authorselect, " ", button("Post entry", async () => {
|
|
5854
|
+
await request({ kind: "swarmblackboard", post: { key: keyinput.value, value: valueinput.value, section: sectionselect.value, author: authorselect.value } });
|
|
5855
|
+
status("The entry landed on the shared board; every agent reads it.");
|
|
5856
|
+
await refresh();
|
|
5857
|
+
}), " ", button("Retirement sweep", async () => {
|
|
5858
|
+
await request({ kind: "swarmblackboard", sweep: true });
|
|
5859
|
+
status("The retirement pass expired the stale entries.");
|
|
5860
|
+
await refresh();
|
|
5861
|
+
}));
|
|
5862
|
+
boardbox.append(postrow);
|
|
5863
|
+
agentsroot.append(boardbox);
|
|
5864
|
+
const orchestrationbox = document.createElement("details");
|
|
5865
|
+
orchestrationbox.className = "sessiongroup";
|
|
5866
|
+
const orchestrationsummary = document.createElement("summary");
|
|
5867
|
+
orchestrationsummary.textContent = "Leader worker topology";
|
|
5868
|
+
orchestrationbox.append(orchestrationsummary);
|
|
5869
|
+
if (swarm.topology !== void 0) {
|
|
5870
|
+
const lead = swarm.agents.find((agent) => agent.id === swarm.topology?.leaderid);
|
|
5871
|
+
const topinfo = document.createElement("p");
|
|
5872
|
+
topinfo.textContent = `Leader ${swarm.topology.leaderid}${lead !== void 0 ? ` (${lead.name})` : ""} by the ${swarm.topology.rule.kind} rule \xB7 ${swarm.topology.workerids.length} workers, ${swarm.topology.criticids.length} critics, ${swarm.topology.verifierids.length} verifiers \xB7 ${swarm.topology.assignments.length} assignment${swarm.topology.assignments.length === 1 ? "" : "s"}.`;
|
|
5873
|
+
orchestrationbox.append(topinfo);
|
|
5874
|
+
const assignments = document.createElement("ul");
|
|
5875
|
+
assignments.className = "audit";
|
|
5876
|
+
for (const assignment of swarm.topology.assignments.slice(0, 8)) {
|
|
5877
|
+
const entry = document.createElement("li");
|
|
5878
|
+
entry.textContent = `${assignment.workerid} \u2192 task ${assignment.taskid}: ${assignment.slice}.`;
|
|
5879
|
+
assignments.append(entry);
|
|
5880
|
+
}
|
|
5881
|
+
orchestrationbox.append(assignments);
|
|
5882
|
+
for (const split of swarm.splits.slice(0, 4)) {
|
|
5883
|
+
const row = document.createElement("p");
|
|
5884
|
+
row.textContent = `Planner executor split: ${split.planownerid} plans, ${split.runownerid} runs${split.taskid !== void 0 ? ` task ${split.taskid}` : ""} with ${split.stepreports.length} step report${split.stepreports.length === 1 ? "" : "s"} (${split.stepreports.filter((report) => report.outcome === "done").length} done).`;
|
|
5885
|
+
orchestrationbox.append(row);
|
|
5886
|
+
}
|
|
5887
|
+
} else {
|
|
5888
|
+
const none = document.createElement("p");
|
|
5889
|
+
none.textContent = "No leader is elected yet; the user elects one by the first or named rule.";
|
|
5890
|
+
orchestrationbox.append(none);
|
|
5891
|
+
}
|
|
5892
|
+
const electionrow = document.createElement("div");
|
|
5893
|
+
electionrow.className = "actions";
|
|
5894
|
+
const leaderselect = document.createElement("select");
|
|
5895
|
+
const firstoption = document.createElement("option");
|
|
5896
|
+
firstoption.value = "first";
|
|
5897
|
+
firstoption.textContent = "first registration";
|
|
5898
|
+
leaderselect.append(firstoption);
|
|
5899
|
+
for (const agent of swarm.agents) {
|
|
5900
|
+
const option = document.createElement("option");
|
|
5901
|
+
option.value = agent.id;
|
|
5902
|
+
option.textContent = `named: ${agent.name}`;
|
|
5903
|
+
leaderselect.append(option);
|
|
5904
|
+
}
|
|
5905
|
+
const splitplan = document.createElement("select");
|
|
5906
|
+
const splitrun = document.createElement("select");
|
|
5907
|
+
const splittask = document.createElement("input");
|
|
5908
|
+
splittask.placeholder = "task id";
|
|
5909
|
+
for (const agent of swarm.agents) {
|
|
5910
|
+
const plan = document.createElement("option");
|
|
5911
|
+
plan.value = agent.id;
|
|
5912
|
+
plan.textContent = agent.name;
|
|
5913
|
+
splitplan.append(plan);
|
|
5914
|
+
const run = document.createElement("option");
|
|
5915
|
+
run.value = agent.id;
|
|
5916
|
+
run.textContent = agent.name;
|
|
5917
|
+
splitrun.append(run);
|
|
5918
|
+
}
|
|
5919
|
+
electionrow.append(leaderselect, " ", button("Elect leader", async () => {
|
|
5920
|
+
await request({ kind: "swarmleader", elect: leaderselect.value === "first" ? { rule: "first" } : { rule: "named", agentid: leaderselect.value } });
|
|
5921
|
+
status("The leader election recorded the topology; the leader only organizes reviewed work.");
|
|
5922
|
+
await refresh();
|
|
5923
|
+
}), " ", button("Assign work", async () => {
|
|
5924
|
+
await request({ kind: "swarmleader", assign: {} });
|
|
5925
|
+
status("The leader sliced the tasks across the workers; every slice still passes the plan review.");
|
|
5926
|
+
await refresh();
|
|
5927
|
+
}), " ", button("Scale workers", async () => {
|
|
5928
|
+
await request({ kind: "swarmleader", scale: { pending: swarm.queue.counts.queued + swarm.queue.counts.claimed } });
|
|
5929
|
+
status("The worker lane scaled by the load under the user configured bound.");
|
|
5930
|
+
await refresh();
|
|
5931
|
+
}), " ", splitplan, " ", splitrun, " ", splittask, " ", button("Split plan and run", async () => {
|
|
5932
|
+
if (splitplan.value === splitrun.value) {
|
|
5933
|
+
status("The planner executor split needs two different agents.");
|
|
5934
|
+
return;
|
|
5935
|
+
}
|
|
5936
|
+
await request({ kind: "swarmleader", split: { planownerid: splitplan.value, runownerid: splitrun.value, ...splittask.value.trim() !== "" ? { taskid: splittask.value } : {} } });
|
|
5937
|
+
status("The task split between the planner and the executor; the executor reports every step back.");
|
|
5938
|
+
await refresh();
|
|
5939
|
+
}));
|
|
5940
|
+
orchestrationbox.append(electionrow);
|
|
5941
|
+
agentsroot.append(orchestrationbox);
|
|
5942
|
+
const boardbox2 = document.createElement("details");
|
|
5943
|
+
boardbox2.className = "sessiongroup";
|
|
5944
|
+
const board2summary = document.createElement("summary");
|
|
5945
|
+
board2summary.textContent = `Progressboard (${swarm.board.lanes.length} lanes)`;
|
|
5946
|
+
boardbox2.append(board2summary);
|
|
5947
|
+
for (const lane of swarm.board.lanes) {
|
|
5948
|
+
const row = document.createElement("p");
|
|
5949
|
+
row.textContent = `${lane.name} (${lane.role}, ${lane.state}) \xB7 lane ${lane.lane}${lane.currenttask !== void 0 ? ` \xB7 working: ${lane.currenttask}` : ""}${lane.milestones.length > 0 ? ` \xB7 ${lane.milestones.filter((milestone) => milestone.done).length}/${lane.milestones.length} milestones (${lane.milestones.map((milestone) => milestone.done ? milestone.label : `${milestone.label} (open)`).join(", ")})` : ""}.`;
|
|
5950
|
+
boardbox2.append(row);
|
|
5951
|
+
}
|
|
5952
|
+
const milestonerow = document.createElement("div");
|
|
5953
|
+
milestonerow.className = "actions";
|
|
5954
|
+
const milestoneagent = document.createElement("select");
|
|
5955
|
+
for (const agent of swarm.agents) {
|
|
5956
|
+
const option = document.createElement("option");
|
|
5957
|
+
option.value = agent.id;
|
|
5958
|
+
option.textContent = agent.name;
|
|
5959
|
+
milestoneagent.append(option);
|
|
5960
|
+
}
|
|
5961
|
+
const milestonelabel = document.createElement("input");
|
|
5962
|
+
milestonelabel.placeholder = "milestone label";
|
|
5963
|
+
milestonerow.append(milestoneagent, " ", milestonelabel, " ", button("Report milestone", async () => {
|
|
5964
|
+
await request({ kind: "swarmleader", milestone: { agentid: milestoneagent.value, label: milestonelabel.value, done: true } });
|
|
5965
|
+
status("The milestone landed on the progressboard snapshot.");
|
|
5966
|
+
await refresh();
|
|
5967
|
+
}), " ", button("Snapshot board", async () => {
|
|
5968
|
+
await request({ kind: "swarmmerge", snapshot: true });
|
|
5969
|
+
status("The progressboard snapshot was stored under the user configured retention.");
|
|
5970
|
+
await refresh();
|
|
5971
|
+
}));
|
|
5972
|
+
boardbox2.append(milestonerow);
|
|
5973
|
+
agentsroot.append(boardbox2);
|
|
5974
|
+
const reviewbox = document.createElement("details");
|
|
5975
|
+
reviewbox.className = "sessiongroup";
|
|
5976
|
+
const reviewsummary = document.createElement("summary");
|
|
5977
|
+
reviewsummary.textContent = `Reviews and verifications (${swarm.reviews.length} verdicts, ${swarm.verifications.length} checks)`;
|
|
5978
|
+
reviewbox.append(reviewsummary);
|
|
5979
|
+
for (const request2 of swarm.reviewrequests.slice(0, 8)) {
|
|
5980
|
+
const row = document.createElement("p");
|
|
5981
|
+
row.textContent = `Review request ${request2.subject}: ${request2.fromagentid} \u2192 ${request2.toagentid}, ${request2.state}${request2.timeoutat !== void 0 ? ` \xB7 deadline ${new Date(request2.timeoutat).toLocaleTimeString()}` : ""}.`;
|
|
5982
|
+
const actions = document.createElement("div");
|
|
5983
|
+
actions.className = "actions";
|
|
5984
|
+
actions.append(button("Ack", async () => {
|
|
5985
|
+
await request({ kind: "swarmreview", ack: request2.id });
|
|
5986
|
+
status("The review request was acked.");
|
|
5987
|
+
await refresh();
|
|
5988
|
+
}));
|
|
5989
|
+
row.append(actions);
|
|
5990
|
+
reviewbox.append(row);
|
|
5991
|
+
}
|
|
5992
|
+
for (const review of swarm.reviews.slice(0, 8)) {
|
|
5993
|
+
const row = document.createElement("p");
|
|
5994
|
+
row.textContent = `Critic verdict ${review.verdict} by ${review.reviewerid} over the output of ${review.subjectagentid}${review.issues.length > 0 ? ` \xB7 issues: ${review.issues.join("; ")}` : ""}${review.requiredchanges.length > 0 ? ` \xB7 required: ${review.requiredchanges.join("; ")}` : ""}.`;
|
|
5995
|
+
reviewbox.append(row);
|
|
5996
|
+
}
|
|
5997
|
+
for (const check of swarm.verifications.slice(0, 8)) {
|
|
5998
|
+
const row = document.createElement("p");
|
|
5999
|
+
const badge = document.createElement("strong");
|
|
6000
|
+
badge.textContent = check.outcome === "pass" ? "PASS" : "FAIL";
|
|
6001
|
+
row.append(`Verifier ${check.verifierid} checked the claim of ${check.claimagentid} by the ${check.method} method: `, badge, ` \u2014 ${check.claim}${check.evidence !== void 0 ? ` (${check.evidence})` : ""}.`);
|
|
6002
|
+
reviewbox.append(row);
|
|
6003
|
+
}
|
|
6004
|
+
const reviewrow = document.createElement("div");
|
|
6005
|
+
reviewrow.className = "actions";
|
|
6006
|
+
const reviewfrom = document.createElement("select");
|
|
6007
|
+
const reviewto = document.createElement("select");
|
|
6008
|
+
for (const agent of swarm.agents) {
|
|
6009
|
+
const one = document.createElement("option");
|
|
6010
|
+
one.value = agent.id;
|
|
6011
|
+
one.textContent = agent.name;
|
|
6012
|
+
reviewfrom.append(one);
|
|
6013
|
+
const two = document.createElement("option");
|
|
6014
|
+
two.value = agent.id;
|
|
6015
|
+
two.textContent = agent.name;
|
|
6016
|
+
reviewto.append(two);
|
|
6017
|
+
}
|
|
6018
|
+
const reviewsubject = document.createElement("input");
|
|
6019
|
+
reviewsubject.placeholder = "review subject";
|
|
6020
|
+
const reviewpayload = document.createElement("input");
|
|
6021
|
+
reviewpayload.placeholder = "output payload";
|
|
6022
|
+
const reviewverdict = document.createElement("select");
|
|
6023
|
+
for (const verdict of ["approve", "changes", "reject"]) {
|
|
6024
|
+
const option = document.createElement("option");
|
|
6025
|
+
option.value = verdict;
|
|
6026
|
+
option.textContent = verdict;
|
|
6027
|
+
reviewverdict.append(option);
|
|
6028
|
+
}
|
|
6029
|
+
const reviewchanges = document.createElement("input");
|
|
6030
|
+
reviewchanges.placeholder = "required changes, semicolon separated";
|
|
6031
|
+
reviewrow.append(reviewfrom, " ", reviewto, " ", reviewsubject, " ", reviewpayload, " ", button("Request review", async () => {
|
|
6032
|
+
await request({ kind: "swarmreview", request: { fromagentid: reviewfrom.value, toagentid: reviewto.value, subject: reviewsubject.value, payload: reviewpayload.value } });
|
|
6033
|
+
status("The review request was routed; the critic reads only.");
|
|
6034
|
+
await refresh();
|
|
6035
|
+
}), " ", reviewverdict, " ", reviewchanges, " ", button("Apply verdict", async () => {
|
|
6036
|
+
const open = swarm.reviewrequests.find((entry) => entry.state === "open" && entry.toagentid === reviewto.value);
|
|
6037
|
+
if (open === void 0) {
|
|
6038
|
+
status("No open review request for the selected reviewer; request one first.");
|
|
6039
|
+
return;
|
|
6040
|
+
}
|
|
6041
|
+
await request({ kind: "swarmreview", apply: { id: open.id, reviewerid: reviewto.value, verdict: reviewverdict.value, issues: [], requiredchanges: reviewchanges.value.split(";").map((change) => change.trim()).filter((change) => change !== "") } });
|
|
6042
|
+
status("The critic verdict was applied; the rework still passes the human review.");
|
|
6043
|
+
await refresh();
|
|
6044
|
+
}), " ", button("Sweep timeouts", async () => {
|
|
6045
|
+
await request({ kind: "swarmreview", sweep: true });
|
|
6046
|
+
status("The review sweep timed out the unanswered requests.");
|
|
6047
|
+
await refresh();
|
|
6048
|
+
}));
|
|
6049
|
+
const verifyrow = document.createElement("div");
|
|
6050
|
+
verifyrow.className = "actions";
|
|
6051
|
+
const verifierselect = document.createElement("select");
|
|
6052
|
+
for (const agent of swarm.agents) {
|
|
6053
|
+
const option = document.createElement("option");
|
|
6054
|
+
option.value = agent.id;
|
|
6055
|
+
option.textContent = agent.name;
|
|
6056
|
+
verifierselect.append(option);
|
|
6057
|
+
}
|
|
6058
|
+
const claimagent = document.createElement("select");
|
|
6059
|
+
for (const agent of swarm.agents) {
|
|
6060
|
+
const option = document.createElement("option");
|
|
6061
|
+
option.value = agent.id;
|
|
6062
|
+
option.textContent = agent.name;
|
|
6063
|
+
claimagent.append(option);
|
|
6064
|
+
}
|
|
6065
|
+
const claimtext = document.createElement("input");
|
|
6066
|
+
claimtext.placeholder = "claim to verify";
|
|
6067
|
+
const claimmethod = document.createElement("input");
|
|
6068
|
+
claimmethod.placeholder = "method";
|
|
6069
|
+
const claimoutcome = document.createElement("select");
|
|
6070
|
+
for (const outcome of ["pass", "fail"]) {
|
|
6071
|
+
const option = document.createElement("option");
|
|
6072
|
+
option.value = outcome;
|
|
6073
|
+
option.textContent = outcome;
|
|
6074
|
+
claimoutcome.append(option);
|
|
6075
|
+
}
|
|
6076
|
+
verifyrow.append(verifierselect, " ", claimagent, " ", claimtext, " ", claimmethod, " ", claimoutcome, " ", button("Verify claim", async () => {
|
|
6077
|
+
await request({ kind: "swarmreview", verify: { verifierid: verifierselect.value, claimagentid: claimagent.value, claim: claimtext.value, method: claimmethod.value, outcome: claimoutcome.value } });
|
|
6078
|
+
status(`The verifier marked the claim ${claimoutcome.value} with the method it used.`);
|
|
6079
|
+
await refresh();
|
|
6080
|
+
}));
|
|
6081
|
+
reviewbox.append(reviewrow, verifyrow);
|
|
6082
|
+
agentsroot.append(reviewbox);
|
|
6083
|
+
const escalationbox = document.createElement("details");
|
|
6084
|
+
escalationbox.className = "sessiongroup";
|
|
6085
|
+
const escalationsummary = document.createElement("summary");
|
|
6086
|
+
escalationsummary.textContent = `Escalation inbox (${swarm.escalations.filter((escalation) => escalation.state === "open").length} open)`;
|
|
6087
|
+
escalationbox.append(escalationsummary);
|
|
6088
|
+
for (const escalation of swarm.escalations.slice(0, 8)) {
|
|
6089
|
+
const row = document.createElement("div");
|
|
6090
|
+
row.className = "sessionrow";
|
|
6091
|
+
const info = document.createElement("p");
|
|
6092
|
+
info.textContent = `${escalation.state === "open" ? "AWAITS THE USER" : "decided"} \xB7 ${escalation.agentid} lifted ${escalation.subject} \u2014 ${escalation.context}${escalation.decision !== void 0 ? ` \xB7 decision: ${escalation.decision}` : ""}.`;
|
|
6093
|
+
row.append(info);
|
|
6094
|
+
if (escalation.state === "open") {
|
|
6095
|
+
const actions = document.createElement("div");
|
|
6096
|
+
actions.className = "actions";
|
|
6097
|
+
const decision = document.createElement("input");
|
|
6098
|
+
decision.placeholder = "the decision the user writes";
|
|
6099
|
+
actions.append(decision, " ", button("Decide", async () => {
|
|
6100
|
+
await request({ kind: "swarmreview", decide: { id: escalation.id, decision: decision.value } });
|
|
6101
|
+
status("The user decision was recorded; the agent continues from it.");
|
|
6102
|
+
await refresh();
|
|
6103
|
+
}));
|
|
6104
|
+
row.append(actions);
|
|
6105
|
+
}
|
|
6106
|
+
escalationbox.append(row);
|
|
6107
|
+
}
|
|
6108
|
+
const escalaterow = document.createElement("div");
|
|
6109
|
+
escalaterow.className = "actions";
|
|
6110
|
+
const escalateagent = document.createElement("select");
|
|
6111
|
+
for (const agent of swarm.agents) {
|
|
6112
|
+
const option = document.createElement("option");
|
|
6113
|
+
option.value = agent.id;
|
|
6114
|
+
option.textContent = agent.name;
|
|
6115
|
+
escalateagent.append(option);
|
|
6116
|
+
}
|
|
6117
|
+
const escalatesubject = document.createElement("input");
|
|
6118
|
+
escalatesubject.placeholder = "stalled subject";
|
|
6119
|
+
const escalatecontext = document.createElement("input");
|
|
6120
|
+
escalatecontext.placeholder = "full context for the user";
|
|
6121
|
+
escalaterow.append(escalateagent, " ", escalatesubject, " ", escalatecontext, " ", button("Escalate to user", async () => {
|
|
6122
|
+
await request({ kind: "swarmreview", escalate: { agentid: escalateagent.value, subject: escalatesubject.value, context: escalatecontext.value } });
|
|
6123
|
+
status("The stalled decision was lifted to the user; the agent waits.");
|
|
6124
|
+
await refresh();
|
|
6125
|
+
}));
|
|
6126
|
+
escalationbox.append(escalaterow);
|
|
6127
|
+
agentsroot.append(escalationbox);
|
|
6128
|
+
const consensusbox = document.createElement("details");
|
|
6129
|
+
consensusbox.className = "sessiongroup";
|
|
6130
|
+
const consensussummary = document.createElement("summary");
|
|
6131
|
+
consensussummary.textContent = `Consensus rounds (${swarm.consensus.length})`;
|
|
6132
|
+
consensusbox.append(consensussummary);
|
|
6133
|
+
for (const round of swarm.consensus.slice(0, 6)) {
|
|
6134
|
+
const yes = round.votes.filter((vote) => vote.vote === "yes").length;
|
|
6135
|
+
const no = round.votes.filter((vote) => vote.vote === "no").length;
|
|
6136
|
+
const abstain = round.votes.filter((vote) => vote.vote === "abstain").length;
|
|
6137
|
+
const row = document.createElement("p");
|
|
6138
|
+
row.textContent = `${round.subject}: ${round.state} \xB7 ${yes} yes, ${no} no, ${abstain} abstain against the quorum ${round.quorum}${round.votes.length > 0 ? ` \xB7 voted by ${round.votes.map((vote) => vote.agentid).join(", ")}` : ""}.`;
|
|
6139
|
+
const actions = document.createElement("div");
|
|
6140
|
+
actions.className = "actions";
|
|
6141
|
+
const voterselect = document.createElement("select");
|
|
6142
|
+
for (const agent of swarm.agents) {
|
|
6143
|
+
const option = document.createElement("option");
|
|
6144
|
+
option.value = agent.id;
|
|
6145
|
+
option.textContent = agent.name;
|
|
6146
|
+
voterselect.append(option);
|
|
6147
|
+
}
|
|
6148
|
+
const voteselect = document.createElement("select");
|
|
6149
|
+
for (const vote of ["yes", "no", "abstain"]) {
|
|
6150
|
+
const option = document.createElement("option");
|
|
6151
|
+
option.value = vote;
|
|
6152
|
+
option.textContent = vote;
|
|
6153
|
+
voteselect.append(option);
|
|
6154
|
+
}
|
|
6155
|
+
actions.append(voterselect, " ", voteselect, " ", button("Vote", async () => {
|
|
6156
|
+
await request({ kind: "swarmreview", vote: { id: round.id, agentid: voterselect.value, vote: voteselect.value } });
|
|
6157
|
+
status(`The vote landed on the round ${round.subject}.`);
|
|
6158
|
+
await refresh();
|
|
6159
|
+
}));
|
|
6160
|
+
row.append(actions);
|
|
6161
|
+
consensusbox.append(row);
|
|
6162
|
+
}
|
|
6163
|
+
const consensusrow = document.createElement("div");
|
|
6164
|
+
consensusrow.className = "actions";
|
|
6165
|
+
const subjectinput2 = document.createElement("input");
|
|
6166
|
+
subjectinput2.placeholder = "consensus subject";
|
|
6167
|
+
const quoruminput = document.createElement("input");
|
|
6168
|
+
quoruminput.placeholder = "quorum";
|
|
6169
|
+
consensusrow.append(subjectinput2, " ", quoruminput, " ", button("Open round", async () => {
|
|
6170
|
+
await request({ kind: "swarmreview", consensus: { subject: subjectinput2.value, ...quoruminput.value.trim() !== "" ? { quorum: Number(quoruminput.value) } : {} } });
|
|
6171
|
+
status("The consensus round opened with the user configured quorum.");
|
|
6172
|
+
await refresh();
|
|
6173
|
+
}));
|
|
6174
|
+
consensusbox.append(consensusrow);
|
|
6175
|
+
agentsroot.append(consensusbox);
|
|
6176
|
+
const handoffbox = document.createElement("details");
|
|
6177
|
+
handoffbox.className = "sessiongroup";
|
|
6178
|
+
const handoffsummary = document.createElement("summary");
|
|
6179
|
+
handoffsummary.textContent = `Handoffs and locks (${swarm.handoffs.length} handoffs, ${swarm.locks.length} locks)`;
|
|
6180
|
+
handoffbox.append(handoffsummary);
|
|
6181
|
+
for (const record of swarm.handoffs.slice(0, 8)) {
|
|
6182
|
+
const row = document.createElement("p");
|
|
6183
|
+
row.textContent = `${record.fromagentid} \u2192 ${record.toagentid}${record.tabid !== void 0 ? ` \xB7 tab ${record.tabid}` : ""} \xB7 ${record.state} \xB7 packaged state: ${record.taskstate}.`;
|
|
6184
|
+
const actions = document.createElement("div");
|
|
6185
|
+
actions.className = "actions";
|
|
6186
|
+
if (record.state === "prepared") actions.append(button("Transfer", async () => {
|
|
6187
|
+
await request({ kind: "swarmhandoff", transfer: record.id });
|
|
6188
|
+
status("The tab moved between the agents under the one agent per tab rule.");
|
|
6189
|
+
await refresh();
|
|
6190
|
+
}), " ");
|
|
6191
|
+
if (record.state === "transferred") actions.append(button("Resume", async () => {
|
|
6192
|
+
await request({ kind: "swarmhandoff", resume: record.id });
|
|
6193
|
+
status("The receiving agent resumed the task from the packaged state.");
|
|
6194
|
+
await refresh();
|
|
6195
|
+
}));
|
|
6196
|
+
row.append(actions);
|
|
6197
|
+
handoffbox.append(row);
|
|
6198
|
+
}
|
|
6199
|
+
const handoffrow = document.createElement("div");
|
|
6200
|
+
handoffrow.className = "actions";
|
|
6201
|
+
const handofffrom = document.createElement("select");
|
|
6202
|
+
const handoffto = document.createElement("select");
|
|
6203
|
+
for (const agent of swarm.agents) {
|
|
6204
|
+
const one = document.createElement("option");
|
|
6205
|
+
one.value = agent.id;
|
|
6206
|
+
one.textContent = agent.name;
|
|
6207
|
+
handofffrom.append(one);
|
|
6208
|
+
const two = document.createElement("option");
|
|
6209
|
+
two.value = agent.id;
|
|
6210
|
+
two.textContent = agent.name;
|
|
6211
|
+
handoffto.append(two);
|
|
6212
|
+
}
|
|
6213
|
+
const handoffstate = document.createElement("input");
|
|
6214
|
+
handoffstate.placeholder = "packaged task state";
|
|
6215
|
+
handoffrow.append(handofffrom, " ", handoffto, " ", handoffstate, " ", button("Prepare handoff", async () => {
|
|
6216
|
+
await request({ kind: "swarmhandoff", prepare: { fromagentid: handofffrom.value, toagentid: handoffto.value, taskstate: handoffstate.value } });
|
|
6217
|
+
status("The handoff was prepared with the packaged task state.");
|
|
6218
|
+
await refresh();
|
|
6219
|
+
}));
|
|
6220
|
+
handoffbox.append(handoffrow);
|
|
6221
|
+
for (const lock of swarm.locks.slice(0, 8)) {
|
|
6222
|
+
const row = document.createElement("p");
|
|
6223
|
+
row.textContent = `Lock ${lock.key} \xB7 ${lock.kind} \xB7 holder ${lock.holder} \xB7 acquired ${new Date(lock.acquiredat).toLocaleTimeString()}${lock.expiresat !== void 0 ? ` \xB7 expires in ${Math.max(Math.round((lock.expiresat - Date.now()) / 1e3), 0)}s` : " \xB7 no expiry"}.`;
|
|
6224
|
+
const actions = document.createElement("div");
|
|
6225
|
+
actions.className = "actions";
|
|
6226
|
+
actions.append(button("Release", async () => {
|
|
6227
|
+
await request({ kind: "swarmlocks", release: { key: lock.key, holder: lock.holder } });
|
|
6228
|
+
status("The lock released and the resource returned to the pool.");
|
|
6229
|
+
await refresh();
|
|
6230
|
+
}));
|
|
6231
|
+
row.append(actions);
|
|
6232
|
+
handoffbox.append(row);
|
|
6233
|
+
}
|
|
6234
|
+
const lockrow = document.createElement("div");
|
|
6235
|
+
lockrow.className = "actions";
|
|
6236
|
+
const lockholder = document.createElement("select");
|
|
6237
|
+
for (const agent of swarm.agents) {
|
|
6238
|
+
const option = document.createElement("option");
|
|
6239
|
+
option.value = agent.id;
|
|
6240
|
+
option.textContent = agent.name;
|
|
6241
|
+
lockholder.append(option);
|
|
6242
|
+
}
|
|
6243
|
+
const lockorigin = document.createElement("input");
|
|
6244
|
+
lockorigin.placeholder = "origin";
|
|
6245
|
+
const lockselector = document.createElement("input");
|
|
6246
|
+
lockselector.placeholder = "selector";
|
|
6247
|
+
const lockkindselect = document.createElement("select");
|
|
6248
|
+
for (const kind of ["exclusive", "shared"]) {
|
|
6249
|
+
const option = document.createElement("option");
|
|
6250
|
+
option.value = kind;
|
|
6251
|
+
option.textContent = kind;
|
|
6252
|
+
lockkindselect.append(option);
|
|
6253
|
+
}
|
|
6254
|
+
lockrow.append(lockholder, " ", lockorigin, " ", lockselector, " ", lockkindselect, " ", button("Acquire lock", async () => {
|
|
6255
|
+
await request({ kind: "swarmlocks", acquire: { holder: lockholder.value, origin: lockorigin.value, selector: lockselector.value, kind: lockkindselect.value } });
|
|
6256
|
+
status("The lock went to the holder; it serializes reviewed work only.");
|
|
6257
|
+
await refresh();
|
|
6258
|
+
}), " ", button("Sweep expired", async () => {
|
|
6259
|
+
await request({ kind: "swarmlocks", sweep: true });
|
|
6260
|
+
status("The expiry sweep returned the abandoned locks to the pool.");
|
|
6261
|
+
await refresh();
|
|
6262
|
+
}));
|
|
6263
|
+
handoffbox.append(lockrow);
|
|
6264
|
+
agentsroot.append(handoffbox);
|
|
6265
|
+
const conflictbox = document.createElement("details");
|
|
6266
|
+
conflictbox.className = "sessiongroup";
|
|
6267
|
+
const conflictsummary = document.createElement("summary");
|
|
6268
|
+
conflictsummary.textContent = `Conflicts and merges (${swarm.conflicts.length} scans)`;
|
|
6269
|
+
conflictbox.append(conflictsummary);
|
|
6270
|
+
for (const scan of swarm.conflicts.slice(0, 6)) {
|
|
6271
|
+
const row = document.createElement("p");
|
|
6272
|
+
row.textContent = scan.clean ? `Scan of ${scan.writers.length} writers: clean, no overlapping write.` : `Scan of ${scan.writers.length} writers: ${scan.overlaps.map((overlap) => `${overlap.origin}|${overlap.selector} by ${overlap.writers.join(", ")}`).join("; ")} \u2014 suggested order ${scan.suggestedorder.join(" \u2192 ")}.`;
|
|
6273
|
+
conflictbox.append(row);
|
|
6274
|
+
}
|
|
6275
|
+
const conflictrow = document.createElement("div");
|
|
6276
|
+
conflictrow.className = "actions";
|
|
6277
|
+
const scanorigin = document.createElement("input");
|
|
6278
|
+
scanorigin.placeholder = "origin";
|
|
6279
|
+
const scanselector = document.createElement("input");
|
|
6280
|
+
scanselector.placeholder = "selector";
|
|
6281
|
+
const scanagents = document.createElement("input");
|
|
6282
|
+
scanagents.placeholder = "writer agent ids, comma separated";
|
|
6283
|
+
conflictrow.append(scanorigin, " ", scanselector, " ", scanagents, " ", button("Scan conflicts", async () => {
|
|
6284
|
+
const writers = scanagents.value.split(",").map((id) => id.trim()).filter((id) => id !== "").map((id) => ({ agentid: id, origin: scanorigin.value, selector: scanselector.value }));
|
|
6285
|
+
await request({ kind: "swarmlocks", scan: { writers } });
|
|
6286
|
+
status("The conflict scan checked the overlapping writes before the parallel runs.");
|
|
6287
|
+
await refresh();
|
|
6288
|
+
}));
|
|
6289
|
+
conflictbox.append(conflictrow);
|
|
6290
|
+
if (swarm.report !== void 0) {
|
|
6291
|
+
const reportinfo = document.createElement("p");
|
|
6292
|
+
reportinfo.textContent = `Merged report ${swarm.report.title}: ${swarm.report.sections.length} section${swarm.report.sections.length === 1 ? "" : "s"} from ${swarm.report.sources.join(", ")}${swarm.report.confidence !== void 0 ? ` \xB7 confidence: ${swarm.report.confidence}` : ""}.`;
|
|
6293
|
+
conflictbox.append(reportinfo);
|
|
6294
|
+
const reportlist = document.createElement("ol");
|
|
6295
|
+
reportlist.className = "audit";
|
|
6296
|
+
for (const section of swarm.report.sections.slice(0, 3)) {
|
|
6297
|
+
const item = document.createElement("li");
|
|
6298
|
+
item.textContent = `${section.title}: ${section.entries.slice(0, 5).map((entry) => `${entry.key} = ${entry.value} (${entry.agentid}${entry.conflict !== void 0 ? `; ${entry.conflict}` : ""})`).join("; ")}.`;
|
|
6299
|
+
reportlist.append(item);
|
|
6300
|
+
}
|
|
6301
|
+
conflictbox.append(reportlist);
|
|
6302
|
+
const exportrow = document.createElement("div");
|
|
6303
|
+
exportrow.className = "actions";
|
|
6304
|
+
exportrow.append(button("Export report", async () => {
|
|
6305
|
+
await request({ kind: "swarmmerge", export: { carriespagecontent: true } });
|
|
6306
|
+
status("The merged report was exported; the page content it carries grades as a data egress event.");
|
|
6307
|
+
await refresh();
|
|
6308
|
+
}));
|
|
6309
|
+
conflictbox.append(exportrow);
|
|
6310
|
+
}
|
|
6311
|
+
const mergerow = document.createElement("div");
|
|
6312
|
+
mergerow.className = "actions";
|
|
6313
|
+
const reporttitle = document.createElement("input");
|
|
6314
|
+
reporttitle.placeholder = "report title";
|
|
6315
|
+
const mergeruleselect = document.createElement("select");
|
|
6316
|
+
for (const rule of ["first", "last", "preferagent", "fail"]) {
|
|
6317
|
+
const option = document.createElement("option");
|
|
6318
|
+
option.value = rule;
|
|
6319
|
+
option.textContent = rule;
|
|
6320
|
+
mergeruleselect.append(option);
|
|
6321
|
+
}
|
|
6322
|
+
const mergeoutputs = document.createElement("input");
|
|
6323
|
+
mergeoutputs.placeholder = "agent:task:key:value triples, semicolon separated";
|
|
6324
|
+
mergerow.append(reporttitle, " ", mergeruleselect, " ", mergeoutputs, " ", button("Build report", async () => {
|
|
6325
|
+
const entries2 = mergeoutputs.value.split(";").map((triple) => triple.split(":")).filter((parts) => parts.length === 4).map((parts) => ({ agentid: parts[0]?.trim() ?? "", taskid: parts[1]?.trim(), key: parts[2]?.trim() ?? "", value: parts[3]?.trim() ?? "" }));
|
|
6326
|
+
await request({ kind: "swarmmerge", entries: entries2, report: { title: reporttitle.value, rule: mergeruleselect.value } });
|
|
6327
|
+
status("The parallel outputs folded into one report with their provenance.");
|
|
6328
|
+
await refresh();
|
|
6329
|
+
}));
|
|
6330
|
+
conflictbox.append(mergerow);
|
|
6331
|
+
const comparerow = document.createElement("div");
|
|
6332
|
+
comparerow.className = "actions";
|
|
6333
|
+
const comparesubject = document.createElement("input");
|
|
6334
|
+
comparesubject.placeholder = "compare subject";
|
|
6335
|
+
const comparefirst = document.createElement("select");
|
|
6336
|
+
const comparesecond = document.createElement("select");
|
|
6337
|
+
for (const agent of swarm.agents) {
|
|
6338
|
+
const one = document.createElement("option");
|
|
6339
|
+
one.value = agent.id;
|
|
6340
|
+
one.textContent = agent.name;
|
|
6341
|
+
comparefirst.append(one);
|
|
6342
|
+
const two = document.createElement("option");
|
|
6343
|
+
two.value = agent.id;
|
|
6344
|
+
two.textContent = agent.name;
|
|
6345
|
+
comparesecond.append(two);
|
|
6346
|
+
}
|
|
6347
|
+
const comparevalue = document.createElement("input");
|
|
6348
|
+
comparevalue.placeholder = "output of the first agent";
|
|
6349
|
+
const comparevalue2 = document.createElement("input");
|
|
6350
|
+
comparevalue2.placeholder = "output of the second agent";
|
|
6351
|
+
comparerow.append(comparesubject, " ", comparefirst, " ", comparevalue, " ", comparesecond, " ", comparevalue2, " ", button("Compare outputs", async () => {
|
|
6352
|
+
await request({ kind: "swarmmerge", compare: { subject: comparesubject.value, outputs: [{ agentid: comparefirst.value, value: comparevalue.value }, { agentid: comparesecond.value, value: comparevalue2.value }] } });
|
|
6353
|
+
status("The competing outputs were contrasted for the user.");
|
|
6354
|
+
await refresh();
|
|
6355
|
+
}));
|
|
6356
|
+
conflictbox.append(comparerow);
|
|
6357
|
+
const lessonrow = document.createElement("div");
|
|
6358
|
+
lessonrow.className = "actions";
|
|
6359
|
+
const lessonagent = document.createElement("select");
|
|
6360
|
+
for (const agent of swarm.agents) {
|
|
6361
|
+
const option = document.createElement("option");
|
|
6362
|
+
option.value = agent.id;
|
|
6363
|
+
option.textContent = agent.name;
|
|
6364
|
+
lessonagent.append(option);
|
|
6365
|
+
}
|
|
6366
|
+
const lessonstatement = document.createElement("input");
|
|
6367
|
+
lessonstatement.placeholder = "verified lesson";
|
|
6368
|
+
const lessonverifier = document.createElement("input");
|
|
6369
|
+
lessonverifier.placeholder = "verified by";
|
|
6370
|
+
lessonrow.append(lessonagent, " ", lessonstatement, " ", lessonverifier, " ", button("Share lesson", async () => {
|
|
6371
|
+
await request({ kind: "swarmmerge", lesson: { agentid: lessonagent.value, statement: lessonstatement.value, verifiedby: lessonverifier.value } });
|
|
6372
|
+
status("The verified lesson landed on the findings section for every agent.");
|
|
6373
|
+
await refresh();
|
|
6374
|
+
}), " ", button("Recompute costs", async () => {
|
|
6375
|
+
await request({ kind: "swarmmerge", costs: true });
|
|
6376
|
+
status("The shared cost accounting summed the per agent usage into the swarm totals.");
|
|
6377
|
+
await refresh();
|
|
6378
|
+
}));
|
|
6379
|
+
conflictbox.append(lessonrow);
|
|
6380
|
+
agentsroot.append(conflictbox);
|
|
6381
|
+
const timelinebox = document.createElement("details");
|
|
6382
|
+
timelinebox.className = "sessiongroup";
|
|
6383
|
+
const timelinesummary = document.createElement("summary");
|
|
6384
|
+
timelinesummary.textContent = `Swarm timeline and costs (${swarm.timeline.length} actions)`;
|
|
6385
|
+
timelinebox.append(timelinesummary);
|
|
6386
|
+
const feed2 = document.createElement("ul");
|
|
6387
|
+
feed2.className = "audit";
|
|
6388
|
+
for (const action of swarm.timeline.slice(-12).reverse()) {
|
|
6389
|
+
const entry = document.createElement("li");
|
|
6390
|
+
entry.textContent = `${new Date(action.at).toLocaleTimeString()} ${action.kind}${action.agentid !== void 0 ? ` (${action.agentid})` : ""}: ${action.summary}`;
|
|
6391
|
+
feed2.append(entry);
|
|
6392
|
+
}
|
|
6393
|
+
timelinebox.append(feed2);
|
|
6394
|
+
const replayrow = document.createElement("div");
|
|
6395
|
+
replayrow.className = "actions";
|
|
6396
|
+
const replayselect = document.createElement("select");
|
|
6397
|
+
for (const agent of swarm.agents) {
|
|
6398
|
+
const option = document.createElement("option");
|
|
6399
|
+
option.value = agent.id;
|
|
6400
|
+
option.textContent = agent.name;
|
|
6401
|
+
replayselect.append(option);
|
|
6402
|
+
}
|
|
6403
|
+
replayrow.append(replayselect, " ", button("Replay agent run", async () => {
|
|
6404
|
+
const replayed = await request({ kind: "swarmmerge", replay: replayselect.value });
|
|
6405
|
+
status(replayed.replay !== void 0 && replayed.replay.length > 0 ? `The replay rebuilt ${replayed.replay.length} recorded actions of the agent.` : "The audit trail holds no recorded action of that agent yet.");
|
|
6406
|
+
await refresh();
|
|
6407
|
+
}));
|
|
6408
|
+
timelinebox.append(replayrow);
|
|
6409
|
+
const latestcost = swarm.costs[0];
|
|
6410
|
+
if (latestcost !== void 0) {
|
|
6411
|
+
const costinfo = document.createElement("p");
|
|
6412
|
+
costinfo.textContent = `Shared costs of ${latestcost.agents} agent${latestcost.agents === 1 ? "" : "s"}: ${latestcost.tokens} tokens \xB7 ${latestcost.cost} ${latestcost.currency ?? ""} \xB7 ${latestcost.steps} steps.`;
|
|
6413
|
+
timelinebox.append(costinfo);
|
|
6414
|
+
}
|
|
6415
|
+
agentsroot.append(timelinebox);
|
|
6416
|
+
if (swarm.events.length > 0) {
|
|
6417
|
+
const eventbox = document.createElement("details");
|
|
6418
|
+
eventbox.className = "sessiongroup";
|
|
6419
|
+
const eventsummary = document.createElement("summary");
|
|
6420
|
+
eventsummary.textContent = `Lifecycle events (${swarm.events.length})`;
|
|
6421
|
+
eventbox.append(eventsummary);
|
|
6422
|
+
const feed = document.createElement("ul");
|
|
6423
|
+
feed.className = "audit";
|
|
6424
|
+
for (const event of swarm.events.slice(0, 10)) {
|
|
6425
|
+
const entry = document.createElement("li");
|
|
6426
|
+
entry.textContent = `${event.kind}: ${event.summary}`;
|
|
6427
|
+
feed.append(entry);
|
|
6428
|
+
}
|
|
6429
|
+
eventbox.append(feed);
|
|
6430
|
+
agentsroot.append(eventbox);
|
|
6431
|
+
}
|
|
6432
|
+
}
|
|
5544
6433
|
//# sourceMappingURL=sidepanel.js.map
|